/** * 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(); $colour = $tokens[$stackPtr]['content']; $expected = strtoupper($colour); if ($colour !== $expected) { $error = 'CSS colours must be defined in uppercase; expected %s but found %s'; $data = array($expected, $colour); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotUpper', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, $expected); } } // Now check if shorthand can be used. if (strlen($colour) !== 7) { return; } if ($colour[1] === $colour[2] && $colour[3] === $colour[4] && $colour[5] === $colour[6]) { $expected = '#' . $colour[1] . $colour[3] . $colour[5]; $error = 'CSS colours must use shorthand if available; expected %s but found %s'; $data = array($expected, $colour); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Shorthand', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, $expected); } } }
/** * 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 ($tokens[$stackPtr + 1]['code'] === T_SEMICOLON) { // No content for this language construct. return; } if ($tokens[$stackPtr + 1]['code'] === T_WHITESPACE) { $content = $tokens[$stackPtr + 1]['content']; $contentLength = strlen($content); if ($contentLength !== 1) { $error = 'Language constructs must be followed by a single space; expected 1 space but found %s'; $data = array($contentLength); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'IncorrectSingle', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } else { if ($tokens[$stackPtr + 1]['code'] !== T_OPEN_PARENTHESIS) { $error = 'Language constructs must be followed by a single space; expected "%s" but found "%s"'; $data = array($tokens[$stackPtr]['content'] . ' ' . $tokens[$stackPtr + 1]['content'], $tokens[$stackPtr]['content'] . $tokens[$stackPtr + 1]['content']); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); if ($fix === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } } //end if }
/** * 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'); } } } }
/** * 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(); $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true); if ($tokens[$prev]['code'] !== T_STYLE) { // The colon is not part of a style definition. return; } if ($tokens[$prev]['content'] === 'progid') { // Special case for IE filters. return; } if ($tokens[$stackPtr - 1]['code'] === T_WHITESPACE) { $error = 'There must be no space before a colon in a style definition'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Before'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr - 1, ''); } } if ($tokens[$stackPtr + 1]['code'] === T_SEMICOLON) { // Empty style definition, ignore it. return; } if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $error = 'Expected 1 space after colon in style definition; 0 found'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoneAfter'); if ($fix === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } else { $content = $tokens[$stackPtr + 1]['content']; if (strpos($content, $phpcsFile->eolChar) === false) { $length = strlen($content); if ($length !== 1) { $error = 'Expected 1 space after colon in style definition; %s found'; $data = array($length); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'After', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } else { $error = 'Expected 1 space after colon in style definition; newline found'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'AfterNewline'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } //end if }
/** * 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(); if ($tokens[$stackPtr]['content'] !== 'opacity') { return; } $next = $phpcsFile->findNext(array(T_COLON, T_WHITESPACE), $stackPtr + 1, null, true); if ($next === false || $tokens[$next]['code'] !== T_DNUMBER && $tokens[$next]['code'] !== T_LNUMBER) { return; } $value = $tokens[$next]['content']; if ($tokens[$next]['code'] === T_LNUMBER) { if ($value !== '0' && $value !== '1') { $error = 'Opacity values must be between 0 and 1'; $phpcsFile->addError($error, $next, 'Invalid'); } } else { if (strlen($value) > 3) { $error = 'Opacity values must have a single value after the decimal point'; $phpcsFile->addError($error, $next, 'DecimalPrecision'); } else { if ($value === '0.0' || $value === '1.0') { $error = 'Opacity value does not require decimal point; use %s instead'; $data = array($value[0]); $fix = $phpcsFile->addFixableError($error, $next, 'PointNotRequired', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($next, $value[0]); } } else { if ($value[0] === '.') { $error = 'Opacity values must not start with a decimal point; use 0%s instead'; $data = array($value); $fix = $phpcsFile->addFixableError($error, $next, 'StartWithPoint', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($next, '0' . $value); } } else { if ($value[0] !== '0') { $error = 'Opacity values must be between 0 and 1'; $phpcsFile->addError($error, $next, 'Invalid'); } } } } //end if } //end if }
/** * 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(); $prevType = $tokens[$stackPtr - 1]['code']; if (isset(Tokens::$emptyTokens[$prevType]) === false) { return; } $nonSpace = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 2, null, true); if ($tokens[$nonSpace]['code'] === T_SEMICOLON) { // Empty statement. return; } $expected = $tokens[$nonSpace]['content'] . ';'; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . ';'; $error = 'Space found before semicolon; expected "%s" but found "%s"'; $data = array($expected, $found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); for ($i = $stackPtr - 1; $i > $nonSpace; $i--) { $phpcsFile->fixer->replaceToken($i, ''); } $phpcsFile->fixer->endChangeset(); } }
/** * 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 int */ public function process(File $phpcsFile, $stackPtr) { $found = $phpcsFile->eolChar; $found = str_replace("\n", '\\n', $found); $found = str_replace("\r", '\\r', $found); $phpcsFile->recordMetric($stackPtr, 'EOL char', $found); if ($found === $this->eolChar) { // Ignore the rest of the file. return $phpcsFile->numTokens + 1; } // Check for single line files without an EOL. This is a very special // case and the EOL char is set to \n when this happens. if ($found === '\\n') { $tokens = $phpcsFile->getTokens(); $lastToken = $phpcsFile->numTokens - 1; if ($tokens[$lastToken]['line'] === 1 && $tokens[$lastToken]['content'] !== "\n") { return; } } $error = 'End of line character is invalid; expected "%s" but found "%s"'; $expected = $this->eolChar; $expected = str_replace("\n", '\\n', $expected); $expected = str_replace("\r", '\\r', $expected); $data = array($expected, $found); // Errors are always reported on line 1, no matter where the first PHP tag is. $fix = $phpcsFile->addFixableError($error, 0, 'InvalidEOLChar', $data); if ($fix === true) { $tokens = $phpcsFile->getTokens(); switch ($this->eolChar) { case '\\n': $eolChar = "\n"; break; case '\\r': $eolChar = "\r"; break; case '\\r\\n': $eolChar = "\r\n"; break; default: $eolChar = $this->eolChar; break; } for ($i = 0; $i < $phpcsFile->numTokens; $i++) { if (isset($tokens[$i + 1]) === false || $tokens[$i + 1]['line'] > $tokens[$i]['line']) { // Token is the last on a line. if (isset($tokens[$i]['orig_content']) === true) { $tokenContent = $tokens[$i]['orig_content']; } else { $tokenContent = $tokens[$i]['content']; } $newContent = rtrim($tokenContent, "\r\n"); $newContent .= $eolChar; $phpcsFile->fixer->replaceToken($i, $newContent); } } } //end if // Ignore the rest of the file. return $phpcsFile->numTokens + 1; }
/** * 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(); // We are only interested in the first token in a multi-line string. if ($tokens[$stackPtr]['code'] === $tokens[$stackPtr - 1]['code']) { return; } $workingString = $tokens[$stackPtr]['content']; $lastStringToken = $stackPtr; $i = $stackPtr + 1; if (isset($tokens[$i]) === true) { while ($i < $phpcsFile->numTokens && $tokens[$i]['code'] === $tokens[$stackPtr]['code']) { $workingString .= $tokens[$i]['content']; $lastStringToken = $i; $i++; } } // Check if it's a double quoted string. if (strpos($workingString, '"') === false) { return; } // Make sure it's not a part of a string started in a previous line. // If it is, then we have already checked it. if ($workingString[0] !== '"') { return; } // The use of variables in double quoted strings is not allowed. if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING) { $stringTokens = token_get_all('<?php ' . $workingString); foreach ($stringTokens as $token) { if (is_array($token) === true && $token[0] === T_VARIABLE) { $error = 'Variable "%s" not allowed in double quoted string; use concatenation instead'; $data = array($token[1]); $phpcsFile->addError($error, $stackPtr, 'ContainsVar', $data); } } return; } //end if $allowedChars = array('\\0', '\\1', '\\2', '\\3', '\\4', '\\5', '\\6', '\\7', '\\n', '\\r', '\\f', '\\t', '\\v', '\\x', '\\b', '\\e', '\\u', '\''); foreach ($allowedChars as $testChar) { if (strpos($workingString, $testChar) !== false) { return; } } $error = 'String %s does not require double quotes; use single quotes instead'; $data = array(str_replace("\n", '\\n', $workingString)); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotRequired', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $innerContent = substr($workingString, 1, -1); $innerContent = str_replace('\\"', '"', $innerContent); $phpcsFile->fixer->replaceToken($stackPtr, "'{$innerContent}'"); while ($lastStringToken !== $stackPtr) { $phpcsFile->fixer->replaceToken($lastStringToken, ''); $lastStringToken--; } $phpcsFile->fixer->endChangeset(); } }
/** * 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(); if (substr($tokens[$stackPtr]['content'], 0, 2) !== '//') { return; } $commentLine = $tokens[$stackPtr]['line']; $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$lastContent]['line'] !== $commentLine) { return; } if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) { return; } // Special case for JS files. if ($tokens[$lastContent]['code'] === T_COMMA || $tokens[$lastContent]['code'] === T_SEMICOLON) { $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, $lastContent - 1, null, true); if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) { return; } } $error = 'Comments may not appear after statements'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found'); if ($fix === true) { $phpcsFile->fixer->addNewlineBefore($stackPtr); } }
/** * 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(); } } }
/** * 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 this file only contains PHP code. for ($i = 0; $i < $phpcsFile->numTokens; $i++) { if ($tokens[$i]['code'] === T_INLINE_HTML && trim($tokens[$i]['content']) !== '') { return $phpcsFile->numTokens; } } // Find the last non-empty token. for ($last = $phpcsFile->numTokens - 1; $last > 0; $last--) { if (trim($tokens[$last]['content']) !== '') { break; } } if ($tokens[$last]['code'] === T_CLOSE_TAG) { $error = 'A closing tag is not permitted at the end of a PHP file'; $fix = $phpcsFile->addFixableError($error, $last, 'NotAllowed'); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($last, $phpcsFile->eolChar); $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $last - 1, null, true); if ($tokens[$prev]['code'] !== T_SEMICOLON && $tokens[$prev]['code'] !== T_CLOSE_CURLY_BRACKET) { $phpcsFile->fixer->addContent($prev, ';'); } $phpcsFile->fixer->endChangeset(); } $phpcsFile->recordMetric($stackPtr, 'PHP closing tag at end of PHP-only file', 'yes'); } else { $phpcsFile->recordMetric($stackPtr, 'PHP closing tag at end of PHP-only file', 'no'); } // Ignore the rest of the file. return $phpcsFile->numTokens; }
/** * 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 sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. * @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(); // PHP 5.4 introduced a shorthand array declaration syntax, so we need // to ignore the these type of array declarations because this sniff is // only dealing with array usage. if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { $openBracket = $stackPtr; } else { if (isset($tokens[$stackPtr]['bracket_opener']) === false) { return; } $openBracket = $tokens[$stackPtr]['bracket_opener']; } $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $openBracket - 1, null, true); if ($tokens[$prev]['code'] === T_EQUAL) { return; } // Square brackets can not have a space before them. $prevType = $tokens[$stackPtr - 1]['code']; if (isset(Tokens::$emptyTokens[$prevType]) === true) { $nonSpace = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 2, null, true); $expected = $tokens[$nonSpace]['content'] . $tokens[$stackPtr]['content']; $found = $phpcsFile->getTokensAsString($nonSpace, $stackPtr - $nonSpace) . $tokens[$stackPtr]['content']; $error = 'Space found before square bracket; expected "%s" but found "%s"'; $data = array($expected, $found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceBeforeBracket', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr - 1, ''); } } // Open square brackets can't ever have spaces after them. if ($tokens[$stackPtr]['code'] === T_OPEN_SQUARE_BRACKET) { $nextType = $tokens[$stackPtr + 1]['code']; if (isset(Tokens::$emptyTokens[$nextType]) === true) { $nonSpace = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 2, null, true); $expected = $tokens[$stackPtr]['content'] . $tokens[$nonSpace]['content']; $found = $phpcsFile->getTokensAsString($stackPtr, $nonSpace - $stackPtr + 1); $error = 'Space found after square bracket; expected "%s" but found "%s"'; $data = array($expected, $found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceAfterBracket', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); } } } }
/** * 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) { if ($this->tabWidth === null) { if (isset($phpcsFile->config->tabWidth) === false || $phpcsFile->config->tabWidth === 0) { // We have no idea how wide tabs are, so assume 4 spaces for fixing. // It shouldn't really matter because indent checks elsewhere in the // standard should fix things up. $this->tabWidth = 4; } else { $this->tabWidth = $phpcsFile->config->tabWidth; } } $checkTokens = array(T_WHITESPACE => true, T_INLINE_HTML => true, T_DOC_COMMENT_WHITESPACE => true); $tokens = $phpcsFile->getTokens(); for ($i = $stackPtr + 1; $i < $phpcsFile->numTokens; $i++) { if ($tokens[$i]['column'] !== 1 || isset($checkTokens[$tokens[$i]['code']]) === false) { continue; } // If tabs are being converted to spaces, the original content // should be used instead of the converted content. if (isset($tokens[$i]['orig_content']) === true) { $content = $tokens[$i]['orig_content']; } else { $content = $tokens[$i]['content']; } if ($content[0] === ' ') { if ($tokens[$i]['code'] === T_DOC_COMMENT_WHITESPACE && $content === ' ') { // Ignore file/class-level DocBlock. continue; } // Space are considered ok if they are proceeded by tabs and not followed // by tabs, as is the case with standard docblock comments. $phpcsFile->recordMetric($i, 'Line indent', 'spaces'); $error = 'Tabs must be used to indent lines; spaces are not allowed'; $fix = $phpcsFile->addFixableError($error, $i, 'SpacesUsed'); if ($fix === true) { $trimmed = ltrim($content, ' '); $numSpaces = strlen($content) - strlen($trimmed); if ($numSpaces < $this->tabWidth) { $numTabs = 1; $padding = "\t"; } else { $numTabs = floor($numSpaces / $this->tabWidth); $remaining = $numSpaces - $numTabs * $this->tabWidth; $padding = str_repeat("\t", $numTabs) . ($padding = str_repeat(' ', $remaining)); } $phpcsFile->fixer->replaceToken($i, $padding . $trimmed); } } else { if ($content[0] === "\t") { $phpcsFile->recordMetric($i, 'Line indent', 'tabs'); } } //end if } //end for // Ignore the rest of the file. return $phpcsFile->numTokens + 1; }
/** * 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) { $error = 'Usage of ELSEIF not allowed; use ELSE IF instead'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotAllowed'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, 'else if'); } }
/** * 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) { if ($phpcsFile->findNext(T_INLINE_HTML, $stackPtr + 1) !== false) { return $phpcsFile->numTokens + 1; } // Skip to the end of the file. $tokens = $phpcsFile->getTokens(); $lastToken = $phpcsFile->numTokens - 1; // Hard-coding the expected \n in this sniff as it is PSR-2 specific and // PSR-2 enforces the use of unix style newlines. if (substr($tokens[$lastToken]['content'], -1) !== "\n") { $error = 'Expected 1 newline at end of file; 0 found'; $fix = $phpcsFile->addFixableError($error, $lastToken, 'NoneFound'); if ($fix === true) { $phpcsFile->fixer->addNewline($lastToken); } $phpcsFile->recordMetric($stackPtr, 'Number of newlines at EOF', '0'); return $phpcsFile->numTokens + 1; } // Go looking for the last non-empty line. $lastLine = $tokens[$lastToken]['line']; if ($tokens[$lastToken]['code'] === T_WHITESPACE) { $lastCode = $phpcsFile->findPrevious(T_WHITESPACE, $lastToken - 1, null, true); } else { $lastCode = $lastToken; } $lastCodeLine = $tokens[$lastCode]['line']; $blankLines = $lastLine - $lastCodeLine + 1; $phpcsFile->recordMetric($stackPtr, 'Number of newlines at EOF', $blankLines); if ($blankLines > 1) { $error = 'Expected 1 blank line at end of file; %s found'; $data = array($blankLines); $fix = $phpcsFile->addFixableError($error, $lastCode, 'TooMany', $data); if ($fix === true) { $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($lastCode, rtrim($tokens[$lastCode]['content'])); for ($i = $lastCode + 1; $i < $lastToken; $i++) { $phpcsFile->fixer->replaceToken($i, ''); } $phpcsFile->fixer->replaceToken($lastToken, $phpcsFile->eolChar); $phpcsFile->fixer->endChangeset(); } } // Skip the rest of the file. return $phpcsFile->numTokens + 1; }
/** * 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) { $this->requiredSpacesAfterOpen = (int) $this->requiredSpacesAfterOpen; $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose; $tokens = $phpcsFile->getTokens(); if (isset($tokens[$stackPtr]['parenthesis_opener']) === false || isset($tokens[$stackPtr]['parenthesis_closer']) === false) { return; } $parenOpener = $tokens[$stackPtr]['parenthesis_opener']; $parenCloser = $tokens[$stackPtr]['parenthesis_closer']; $spaceAfterOpen = 0; if ($tokens[$parenOpener + 1]['code'] === T_WHITESPACE) { if (strpos($tokens[$parenOpener + 1]['content'], $phpcsFile->eolChar) !== false) { $spaceAfterOpen = 'newline'; } else { $spaceAfterOpen = strlen($tokens[$parenOpener + 1]['content']); } } $phpcsFile->recordMetric($stackPtr, 'Spaces after control structure open parenthesis', $spaceAfterOpen); if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) { $error = 'Expected %s spaces after opening bracket; %s found'; $data = array($this->requiredSpacesAfterOpen, $spaceAfterOpen); $fix = $phpcsFile->addFixableError($error, $parenOpener + 1, 'SpacingAfterOpenBrace', $data); if ($fix === true) { $padding = str_repeat(' ', $this->requiredSpacesAfterOpen); if ($spaceAfterOpen === 0) { $phpcsFile->fixer->addContent($parenOpener, $padding); } else { if ($spaceAfterOpen === 'newline') { $phpcsFile->fixer->replaceToken($parenOpener + 1, ''); } else { $phpcsFile->fixer->replaceToken($parenOpener + 1, $padding); } } } } if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']) { $spaceBeforeClose = 0; if ($tokens[$parenCloser - 1]['code'] === T_WHITESPACE) { $spaceBeforeClose = strlen(ltrim($tokens[$parenCloser - 1]['content'], $phpcsFile->eolChar)); } $phpcsFile->recordMetric($stackPtr, 'Spaces before control structure close parenthesis', $spaceBeforeClose); if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) { $error = 'Expected %s spaces before closing bracket; %s found'; $data = array($this->requiredSpacesBeforeClose, $spaceBeforeClose); $fix = $phpcsFile->addFixableError($error, $parenCloser - 1, 'SpaceBeforeCloseBrace', $data); if ($fix === true) { $padding = str_repeat(' ', $this->requiredSpacesBeforeClose); if ($spaceBeforeClose === 0) { $phpcsFile->fixer->addContentBefore($parenCloser, $padding); } else { $phpcsFile->fixer->replaceToken($parenCloser - 1, $padding); } } } } //end if }
/** * 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(); // If this is an inline condition (ie. there is no scope opener), then // return, as this is not a new scope. if (isset($tokens[$stackPtr]['scope_closer']) === false) { return; } // We need to actually find the first piece of content on this line, // as if this is a method with tokens before it (public, static etc) // or an if with an else before it, then we need to start the scope // checking from there, rather than the current token. $lineStart = $phpcsFile->findFirstOnLine(T_WHITESPACE, $stackPtr, true); $startColumn = $tokens[$lineStart]['column']; $scopeStart = $tokens[$stackPtr]['scope_opener']; $scopeEnd = $tokens[$stackPtr]['scope_closer']; // Check that the closing brace is on it's own line. $lastContent = $phpcsFile->findPrevious(array(T_INLINE_HTML, T_WHITESPACE, T_OPEN_TAG), $scopeEnd - 1, $scopeStart, true); if ($tokens[$lastContent]['line'] === $tokens[$scopeEnd]['line']) { $error = 'Closing brace must be on a line by itself'; $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'ContentBefore'); if ($fix === true) { $phpcsFile->fixer->addNewlineBefore($scopeEnd); } return; } // Check now that the closing brace is lined up correctly. $lineStart = $phpcsFile->findFirstOnLine(T_WHITESPACE, $scopeEnd, true); $braceIndent = $tokens[$lineStart]['column']; if ($tokens[$stackPtr]['code'] !== T_DEFAULT && $tokens[$stackPtr]['code'] !== T_CASE && $braceIndent !== $startColumn) { $error = 'Closing brace indented incorrectly; expected %s spaces, found %s'; $data = array($startColumn - 1, $braceIndent - 1); $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'Indent', $data); if ($fix === true) { $diff = $startColumn - $braceIndent; if ($diff > 0) { $phpcsFile->fixer->addContentBefore($scopeEnd, str_repeat(' ', $diff)); } else { $phpcsFile->fixer->substrToken($scopeEnd - 1, 0, $diff); } } } //end if }
/** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The current file being checked. * @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 there is one space before the operator. if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { $error = 'Expected 1 space before logical operator; 0 found'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceBefore'); if ($fix === true) { $phpcsFile->fixer->addContentBefore($stackPtr, ' '); } } else { $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); if ($tokens[$stackPtr]['line'] === $tokens[$prev]['line'] && strlen($tokens[$stackPtr - 1]['content']) !== 1) { $found = strlen($tokens[$stackPtr - 1]['content']); $error = 'Expected 1 space before logical operator; %s found'; $data = array($found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'TooMuchSpaceBefore', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr - 1, ' '); } } } // Check there is one space after the operator. if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $error = 'Expected 1 space after logical operator; 0 found'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfter'); if ($fix === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } } else { $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); if ($tokens[$stackPtr]['line'] === $tokens[$next]['line'] && strlen($tokens[$stackPtr + 1]['content']) !== 1) { $found = strlen($tokens[$stackPtr + 1]['content']); $error = 'Expected 1 space after logical operator; %s found'; $data = array($found); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'TooMuchSpaceAfter', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } } }
/** * 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 ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $error = 'A cast statement must be followed by a single space'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpace'); if ($fix === true) { $phpcsFile->fixer->addContent($stackPtr, ' '); } $phpcsFile->recordMetric($stackPtr, 'Spacing after cast statement', 0); return; } $phpcsFile->recordMetric($stackPtr, 'Spacing after cast statement', $tokens[$stackPtr + 1]['length']); if ($tokens[$stackPtr + 1]['length'] !== 1) { $error = 'A cast statement must be followed by a single space'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'TooMuchSpace'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ' '); } } }
/** * 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 ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { return; } $error = 'A cast statement must not be followed by a space'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceFound'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); } }
/** * Process the tokens that this sniff is listening for. * * @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(); $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true); if ($tokens[$prev]['code'] === T_COMMA) { $error = 'Last member of object must not be followed by a comma'; $fix = $phpcsFile->addFixableError($error, $prev, 'Missing'); if ($fix === true) { $phpcsFile->fixer->replaceToken($prev, ''); } } }
/** * 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(); $content = $tokens[$stackPtr]['content']; if ($content !== strtolower($content)) { $error = '%s keyword must be lowercase; expected "%s" but found "%s"'; $data = array(strtoupper($content), strtolower($content), $content); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'FoundUppercase', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, strtolower($content)); } } }
/** * 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 ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { $before = 0; } else { if ($tokens[$stackPtr - 2]['line'] !== $tokens[$stackPtr]['line']) { $before = 'newline'; } else { $before = $tokens[$stackPtr - 1]['length']; } } if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { $after = 0; } else { if ($tokens[$stackPtr + 2]['line'] !== $tokens[$stackPtr]['line']) { $after = 'newline'; } else { $after = $tokens[$stackPtr + 1]['length']; } } $phpcsFile->recordMetric($stackPtr, 'Spacing before object operator', $before); $phpcsFile->recordMetric($stackPtr, 'Spacing after object operator', $after); if ($before !== 0 && ($before !== 'newline' || $this->ignoreNewlines === false)) { $error = 'Space found before object operator'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Before'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr - 1, ''); } } if ($after !== 0 && ($after !== 'newline' || $this->ignoreNewlines === false)) { $error = 'Space found after object operator'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'After'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); } } }
/** * 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(); $colon = $phpcsFile->findNext(T_COLON, $stackPtr + 1); if ($colon !== $stackPtr + 1) { $error = 'There must be no space before the colon in a property/label declaration'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Before'); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr + 1, ''); } } if ($tokens[$colon + 1]['code'] !== T_WHITESPACE || $tokens[$colon + 1]['content'] !== ' ') { $error = 'There must be a single space after the colon in a property/label declaration'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'After'); if ($fix === true) { if ($tokens[$colon + 1]['code'] === T_WHITESPACE) { $phpcsFile->fixer->replaceToken($colon + 1, ' '); } else { $phpcsFile->fixer->addContent($colon, ' '); } } } }
/** * 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) { $phpcsFile->recordMetric($stackPtr, 'Short array syntax used', 'yes'); $error = 'Short array syntax is not allowed'; $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found'); if ($fix === true) { $tokens = $phpcsFile->getTokens(); $opener = $tokens[$stackPtr]['bracket_opener']; $closer = $tokens[$stackPtr]['bracket_closer']; $phpcsFile->fixer->beginChangeset(); $phpcsFile->fixer->replaceToken($opener, 'array('); $phpcsFile->fixer->replaceToken($closer, ')'); $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(); $content = $tokens[$stackPtr]['content']; $expected = str_replace(' ', '', $content); $expected = str_replace("\t", '', $expected); if ($content !== $expected) { $error = 'Cast statements must not contain whitespace; expected "%s" but found "%s"'; $data = array($expected, $content); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContainsWhiteSpace', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($stackPtr, $expected); } } }
/** * 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(); $semicolon = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1); if ($semicolon === false || $tokens[$semicolon]['line'] !== $tokens[$stackPtr]['line']) { $error = 'Style definitions must end with a semicolon'; $phpcsFile->addError($error, $stackPtr, 'NotAtEnd'); return; } if ($tokens[$semicolon - 1]['code'] === T_WHITESPACE) { $length = strlen($tokens[$semicolon - 1]['content']); $error = 'Expected 0 spaces before semicolon in style definition; %s found'; $data = array($length); $fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpaceFound', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($semicolon - 1, ''); } } }
/** * 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_STYLE, $stackPtr + 1); if ($next === false) { return; } if ($tokens[$next]['content'] === 'progid') { // Special case for IE filters. return; } if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) { $error = 'Each style definition must be on a line by itself'; $fix = $phpcsFile->addFixableError($error, $next, 'Found'); if ($fix === true) { $phpcsFile->fixer->addNewlineBefore($next); } } }