Initial commit: apps.supersam24.ru

This commit is contained in:
root committed 2026-10-22 00:04:27 +03:00
commit e955e1da36
6566 files changed
+1271095

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
; This file is for unifying the coding style for different editors and IDEs.
; More information at http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.bat]
end_of_line = crlf
[*.yml]
indent_size = 2
@@ -0,0 +1,10 @@
# Define the line ending behavior of the different file extensions
# Set default behaviour, in case users don't have core.autocrlf set.
* text=lf
# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.php eol=lf
# Declare files that will always have CRLF line endings on checkout.
*.bat eol=crlf
@@ -0,0 +1,6 @@
/build/
/dist/
tags
composer.lock
vendor/
/.idea/
+37
View File
@@ -0,0 +1,37 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4snapshot
matrix:
fast_finish: true
include:
- php: 7.2
env: PHPCS=1
before_install:
- if [[ $TRAVIS_PHP_VERSION != "7.4snapshot" ]]; then phpenv config-rm xdebug.ini; fi
before_script:
- composer install --prefer-source
script:
- if [[ $PHPCS != 1 && $TRAVIS_PHP_VERSION = 7.1 ]]; then composer run-script test-coverage --timeout=0; fi
- if [[ $PHPCS != 1 && $TRAVIS_PHP_VERSION != 7.1 ]]; then composer test; fi
- if [[ $PHPCS = 1 ]]; then composer cs-check; fi
after_success:
- if [[ $PHPCS != 1 && $TRAVIS_PHP_VERSION = 7.1 ]]; then bash <(curl -s https://codecov.io/bash); fi
cache:
directories:
- $HOME/.composer/cache
notifications:
email: false
@@ -0,0 +1,88 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 1.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\Commenting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Ensures doc block alignments.
*/
class DocBlockAlignmentSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_DOC_COMMENT_OPEN_TAG];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$commentClose = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $stackPtr);
$afterComment = $phpcsFile->findNext(T_WHITESPACE, $commentClose + 1, null, true);
$commentIndentation = $tokens[$stackPtr]['column'] - 1;
$codeIndentation = $tokens[$afterComment]['column'] - 1;
// Check for doc block opening being misaligned
if ($commentIndentation != $codeIndentation) {
$msg = 'Doc block not aligned with code; expected indentation of %s but found %s';
$data = [$codeIndentation, $commentIndentation];
$fix = $phpcsFile->addFixableError($msg, $stackPtr, 'DocBlockMisaligned', $data);
if ($fix === true) {
// Collect tokens to change indentation of
$tokensToIndent = [
$stackPtr => $codeIndentation,
];
$commentOpenLine = $tokens[$stackPtr]['line'];
$commentCloseLine = $tokens[$commentClose]['line'];
$lineBreaksInComment = $commentCloseLine - $commentOpenLine;
if ($lineBreaksInComment !== 0) {
$searchToken = $stackPtr + 1;
do {
$commentBorder = $phpcsFile->findNext(
[T_DOC_COMMENT_STAR, T_DOC_COMMENT_CLOSE_TAG],
$searchToken,
$commentClose + 1
);
if ($commentBorder !== false) {
$tokensToIndent[$commentBorder] = $codeIndentation + 1;
$searchToken = $commentBorder + 1;
}
} while ($commentBorder !== false);
}
// Update indentation
$phpcsFile->fixer->beginChangeset();
foreach ($tokensToIndent as $searchToken => $indent) {
$indentString = str_repeat(' ', $indent);
$isOpenTag = $tokens[$searchToken]['type'] === 'T_DOC_COMMENT_OPEN_TAG';
if ($isOpenTag && $commentIndentation === 0) {
$phpcsFile->fixer->addContentBefore($searchToken, $indentString);
} else {
$phpcsFile->fixer->replaceToken($searchToken - 1, $indentString);
}
}
$phpcsFile->fixer->endChangeset();
}
}
}
}
@@ -0,0 +1,479 @@
<?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-2014 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
namespace CakePHP\Sniffs\Commenting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\FunctionCommentSniff as PearFunctionCommentSniff;
use PHP_CodeSniffer\Util\Common;
/**
* Parses and verifies the doc comments for functions.
*
* Verifies that :
* <ul>
* <li>A comment exists</li>
* <li>There is a blank newline after the short description</li>
* <li>There is a blank newline between the long and short description</li>
* <li>There is a blank newline between the long description and tags</li>
* <li>Parameter names represent those in the method</li>
* <li>Parameter comments are in the correct order</li>
* <li>Parameter comments are complete</li>
* <li>A type hint is provided for array and custom class</li>
* <li>Type hint matches the actual variable/class type</li>
* <li>A blank line is present before the first and after the last parameter</li>
* <li>A return type exists</li>
* <li>Any throw tag must have a comment</li>
* <li>The tag order and indentation are correct</li>
* </ul>
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class FunctionCommentSniff extends PearFunctionCommentSniff
{
/**
* Is the comment an inheritdoc?
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in the stack passed in $tokens.
* @return bool True if the comment is an inheritdoc
*/
protected function isInheritDoc(File $phpcsFile, $stackPtr)
{
$start = $phpcsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPtr - 1);
$end = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $start);
$content = $phpcsFile->getTokensAsString($start, ($end - $start));
return preg_match('/{@inheritDoc}|@inheritDoc/i', $content) === 1;
}
/**
* Process the return comment of this function comment.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in the stack passed in $tokens.
* @param int $commentStart The position in the stack where the comment started.
* @return void
*/
protected function processReturn(File $phpcsFile, $stackPtr, $commentStart)
{
if ($this->isInheritDoc($phpcsFile, $stackPtr)) {
return;
}
$tokens = $phpcsFile->getTokens();
// Skip constructor and destructor.
$className = '';
foreach ($tokens[$stackPtr]['conditions'] as $condPtr => $condition) {
if ($condition === T_CLASS || $condition === T_INTERFACE) {
$className = $phpcsFile->getDeclarationName($condPtr);
$className = strtolower(ltrim($className, '_'));
}
}
$methodName = $phpcsFile->getDeclarationName($stackPtr);
$isSpecialMethod = ($methodName === '__construct' || $methodName === '__destruct');
if ($methodName !== '_') {
$methodName = strtolower(ltrim($methodName, '_'));
}
$return = null;
foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
if ($tokens[$tag]['content'] === '@return') {
if ($return !== null) {
$error = 'Only 1 @return tag is allowed in a function comment';
$phpcsFile->addError($error, $tag, 'DuplicateReturn');
return;
}
$return = $tag;
}
}
if ($isSpecialMethod === true) {
return;
}
if ($return === null) {
$error = 'Missing @return tag in function comment';
$phpcsFile->addWarning($error, $tokens[$commentStart]['comment_closer'], 'MissingReturn');
return;
}
$content = $tokens[($return + 2)]['content'];
if (empty($content) === true || $tokens[($return + 2)]['code'] !== T_DOC_COMMENT_STRING) {
$error = 'Return type missing for @return tag in function comment';
$phpcsFile->addError($error, $return, 'MissingReturnType');
return;
}
// Check return type (can be multiple, separated by '|').
list($types, ) = explode(' ', $content);
$typeNames = explode('|', $types);
$suggestedNames = [];
foreach ($typeNames as $i => $typeName) {
if ($typeName === 'integer') {
$suggestedName = 'int';
} elseif ($typeName === 'boolean') {
$suggestedName = 'bool';
} elseif (in_array($typeName, ['int', 'bool'])) {
$suggestedName = $typeName;
} else {
$suggestedName = Common::suggestType($typeName);
}
if (in_array($suggestedName, $suggestedNames) === false) {
$suggestedNames[] = $suggestedName;
}
}
$suggestedType = implode('|', $suggestedNames);
if ($types !== $suggestedType) {
$error = 'Expected "%s" but found "%s" for function return type';
$data = [
$suggestedType,
$types,
];
$phpcsFile->addError($error, $return, 'InvalidReturn', $data);
}
$endToken = isset($tokens[$stackPtr]['scope_closer']) ? $tokens[$stackPtr]['scope_closer'] : false;
if (!$endToken) {
return;
}
// If the return type is void, make sure there is
// no non-void return statements in the function.
if ($typeNames === ['void']) {
for ($returnToken = $stackPtr; $returnToken < $endToken; $returnToken++) {
if ($tokens[$returnToken]['code'] === T_CLOSURE) {
$returnToken = $tokens[$returnToken]['scope_closer'];
continue;
}
if (
$tokens[$returnToken]['code'] === T_RETURN
|| $tokens[$returnToken]['code'] === T_YIELD
|| $tokens[$returnToken]['code'] === T_YIELD_FROM
) {
break;
}
}
if ($returnToken !== $endToken) {
// If the function is not returning anything, just
// exiting, then there is no problem.
$semicolon = $phpcsFile->findNext(T_WHITESPACE, ($returnToken + 1), null, true);
if ($tokens[$semicolon]['code'] !== T_SEMICOLON) {
$error = 'Function return type is void, but function contains return statement';
$phpcsFile->addWarning($error, $return, 'InvalidReturnVoid');
}
}
return;
}
// If return type is not void, there needs to be a return statement
// somewhere in the function that returns something.
if (!in_array('mixed', $typeNames, true) && !in_array('void', $typeNames, true)) {
$returnToken = $phpcsFile->findNext([T_RETURN, T_YIELD, T_YIELD_FROM], $stackPtr, $endToken);
if ($returnToken === false) {
$error = 'Function return type is not void, but function has no return statement';
$phpcsFile->addWarning($error, $return, 'InvalidNoReturn');
} else {
$semicolon = $phpcsFile->findNext(T_WHITESPACE, ($returnToken + 1), null, true);
if ($tokens[$semicolon]['code'] === T_SEMICOLON) {
$error = 'Function return type is not void, but function is returning void here';
$phpcsFile->addWarning($error, $returnToken, 'InvalidReturnNotVoid');
}
}
}
}
/**
* Process any throw tags that this function comment has.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in the stack passed in $tokens.
* @param int $commentStart The position in the stack where the comment started.
* @return void
*/
protected function processThrows(File $phpcsFile, $stackPtr, $commentStart)
{
$tokens = $phpcsFile->getTokens();
foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) {
if ($tokens[$tag]['content'] !== '@throws') {
continue;
}
$exception = $comment = null;
if ($tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING) {
$matches = [];
preg_match('/([^\s]+)(?:\s+(.*))?/', $tokens[($tag + 2)]['content'], $matches);
$exception = $matches[1];
if (isset($matches[2]) === true) {
$comment = $matches[2];
}
}
if ($exception === null) {
$error = 'Exception type and comment missing for @throws tag in function comment';
$phpcsFile->addWarning($error, $tag, 'InvalidThrows');
} elseif ($comment === null) {
$error = 'Comment missing for @throws tag in function comment';
$phpcsFile->addWarning($error, $tag, 'EmptyThrows');
} else {
// Any strings until the next tag belong to this comment.
if (isset($tokens[$commentStart]['comment_tags'][($pos + 1)]) === true) {
$end = $tokens[$commentStart]['comment_tags'][($pos + 1)];
} else {
$end = $tokens[$commentStart]['comment_closer'];
}
for ($i = ($tag + 3); $i < $end; $i++) {
if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) {
$comment .= ' ' . $tokens[$i]['content'];
}
}
// Starts with a capital letter and ends with a fullstop.
$firstChar = $comment[0];
if (strtoupper($firstChar) !== $firstChar) {
$error = '@throws tag comment must start with a capital letter';
$phpcsFile->addWarning($error, ($tag + 2), 'ThrowsNotCapital');
}
$lastChar = substr($comment, -1);
if ($lastChar !== '.') {
$error = '@throws tag comment must end with a full stop';
$phpcsFile->addWarning($error, ($tag + 2), 'ThrowsNoFullStop');
}
}
}
}
/**
* Process the function parameter comments.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in the stack passed in $tokens.
* @param int $commentStart The position in the stack where the comment started.
* @return void
*/
protected function processParams(File $phpcsFile, $stackPtr, $commentStart)
{
if ($this->isInheritDoc($phpcsFile, $stackPtr)) {
return;
}
$tokens = $phpcsFile->getTokens();
$params = [];
$maxType = $maxVar = 0;
foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) {
if ($tokens[$tag]['content'] !== '@param') {
continue;
}
$type = $var = $comment = '';
$typeSpace = $varSpace = 0;
$commentLines = [];
if ($tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING) {
$matches = [];
preg_match('/([^$&]+)(?:((?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $tokens[($tag + 2)]['content'], $matches);
$typeLen = strlen($matches[1]);
$type = trim($matches[1]);
$typeSpace = ($typeLen - strlen($type));
$typeLen = strlen($type);
if ($typeLen > $maxType) {
$maxType = $typeLen;
}
if (isset($matches[2]) === true) {
$var = $matches[2];
$varLen = strlen($var);
if ($varLen > $maxVar) {
$maxVar = $varLen;
}
if (isset($matches[4]) === true) {
$varSpace = strlen($matches[3]);
$comment = $matches[4];
$commentLines[] = [
'comment' => $comment,
'token' => ($tag + 2),
'indent' => $varSpace,
];
// Any strings until the next tag belong to this comment.
if (isset($tokens[$commentStart]['comment_tags'][($pos + 1)]) === true) {
$end = $tokens[$commentStart]['comment_tags'][($pos + 1)];
} else {
$end = $tokens[$commentStart]['comment_closer'];
}
for ($i = ($tag + 3); $i < $end; $i++) {
if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) {
$indent = 0;
if ($tokens[($i - 1)]['code'] === T_DOC_COMMENT_WHITESPACE) {
$indent = strlen($tokens[($i - 1)]['content']);
}
$comment .= ' ' . $tokens[$i]['content'];
$commentLines[] = [
'comment' => $tokens[$i]['content'],
'token' => $i,
'indent' => $indent,
];
}
}
} else {
$error = 'Missing parameter comment';
$phpcsFile->addError($error, $tag, 'MissingParamComment');
$commentLines[] = ['comment' => ''];
}
} else {
$error = 'Missing parameter name';
$phpcsFile->addError($error, $tag, 'MissingParamName');
}
} else {
$error = 'Missing parameter type';
$phpcsFile->addError($error, $tag, 'MissingParamType');
}
$params[] = compact('tag', 'type', 'var', 'comment', 'commentLines', 'typeSpace', 'varSpace');
}
$realParams = $phpcsFile->getMethodParameters($stackPtr);
$foundParams = [];
foreach ($params as $pos => $param) {
// If the type is empty, the whole line is empty.
if ($param['type'] === '') {
continue;
}
// Check the param type value.
$typeNames = explode('|', $param['type']);
foreach ($typeNames as $typeName) {
if ($typeName === 'integer') {
$suggestedName = 'int';
} elseif ($typeName === 'boolean') {
$suggestedName = 'bool';
} elseif (in_array($typeName, ['int', 'bool'])) {
$suggestedName = $typeName;
} else {
$suggestedName = Common::suggestType($typeName);
}
if ($typeName !== $suggestedName) {
$error = 'Expected "%s" but found "%s" for parameter type';
$data = [$suggestedName, $typeName];
$fix = $phpcsFile->addFixableError($error, $param['tag'], 'IncorrectParamVarName', $data);
if ($fix === true) {
$content = $suggestedName;
$content .= str_repeat(' ', $param['typeSpace']);
$content .= $param['var'];
$content .= str_repeat(' ', $param['varSpace']);
if (isset($param['commentLines'][0])) {
$content .= $param['commentLines'][0]['comment'];
}
$phpcsFile->fixer->replaceToken(($param['tag'] + 2), $content);
}
}
}
if ($param['var'] === '') {
continue;
}
$foundParams[] = $param['var'];
// Make sure the param name is correct.
if (isset($realParams[$pos]) === true) {
$realName = $realParams[$pos]['name'];
if ($realName !== $param['var']) {
$code = 'ParamNameNoMatch';
$data = [$param['var'], $realName];
$error = 'Doc comment for parameter %s does not match ';
if (strtolower($param['var']) === strtolower($realName)) {
$error .= 'case of ';
$code = 'ParamNameNoCaseMatch';
}
$error .= 'actual variable name %s';
$fix = $phpcsFile->addFixableWarning($error, $param['tag'], $code, $data);
if ($fix === true) {
$content = $suggestedName;
$content .= str_repeat(' ', $param['typeSpace']);
$content .= $realName;
$content .= str_repeat(' ', $param['varSpace']);
$content .= $param['commentLines'][0]['comment'];
$phpcsFile->fixer->replaceToken(($param['tag'] + 2), $content);
}
}
} elseif (substr($param['var'], -4) !== ',...') {
// We must have an extra parameter comment.
$error = 'Superfluous parameter comment';
$phpcsFile->addError($error, $param['tag'], 'ExtraParamComment');
}
if ($param['comment'] === '') {
continue;
}
// Param comments must start with a capital letter and end with the full stop.
$firstChar = $param['comment'][0];
if (preg_match('|\p{Lu}|u', $firstChar) === 0) {
$error = 'Parameter comment must start with a capital letter';
$phpcsFile->addWarning($error, $param['tag'], 'ParamCommentNotCapital');
}
$lastChar = substr($param['comment'], -1);
if ($lastChar !== '.') {
$error = 'Parameter comment must end with a full stop';
$phpcsFile->addWarning($error, $param['tag'], 'ParamCommentFullStop');
}
}
$realNames = [];
foreach ($realParams as $realParam) {
$realNames[] = $realParam['name'];
}
// Report missing comments.
$diff = array_diff($realNames, $foundParams);
foreach ($diff as $neededParam) {
$error = 'Doc comment for parameter "%s" missing';
$data = [$neededParam];
$phpcsFile->addWarning($error, $commentStart, 'MissingParamTag', $data);
}
}
}
@@ -0,0 +1,62 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.14
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Ensures curly brackets are used with if, else, elseif, foreach and for.
* while and dowhile are covered elsewhere
*
*/
namespace CakePHP\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class ControlStructuresSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_IF, T_ELSEIF, T_ELSE, T_FOREACH, T_FOR];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$nextToken]['code'] === T_OPEN_PARENTHESIS) {
$closer = $tokens[$nextToken]['parenthesis_closer'];
$diff = $closer - $stackPtr;
$nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + $diff + 1), null, true);
}
if ($tokens[$nextToken]['code'] === T_IF) {
// "else if" is not checked by this sniff, another sniff takes care of that.
return;
}
if ($tokens[$nextToken]['code'] !== T_OPEN_CURLY_BRACKET && $tokens[$nextToken]['code'] !== T_COLON) {
$error = 'Curly brackets required for if/elseif/else.';
$phpcsFile->addError($error, $stackPtr, 'NotAllowed');
}
}
}
@@ -0,0 +1,53 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.14
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Ensures that elseif is used instead of else if
*
*/
class ElseIfDeclarationSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_ELSE];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$nextToken]['code'] !== T_IF) {
return;
}
$error = 'Usage of ELSE IF not allowed; use ELSEIF instead';
$phpcsFile->addError($error, $stackPtr, 'NotAllowed');
}
}
@@ -0,0 +1,61 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.14
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\ControlStructures;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Ensures that while and do-while use curly brackets
*
*/
class WhileStructuresSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_DO, T_WHILE];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$nextToken]['code'] === T_OPEN_PARENTHESIS) {
$closer = $tokens[$nextToken]['parenthesis_closer'];
$diff = $closer - $stackPtr;
$nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + $diff + 1), null, true);
}
if ($tokens[$stackPtr]['code'] === T_WHILE && $tokens[$nextToken]['code'] === T_SEMICOLON) {
/* This while is probably part of a do-while construction, skip it .. */
return;
}
if ($tokens[$nextToken]['code'] !== T_OPEN_CURLY_BRACKET && $tokens[$nextToken]['code'] !== T_COLON) {
$error = 'Curly brackets required in a do-while or while loop';
$phpcsFile->addError($error, $stackPtr, 'NotAllowed');
}
}
}
@@ -0,0 +1,80 @@
<?php
namespace CakePHP\Sniffs\Formatting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Throws errors if there's no blank line before return statements.
*
* @author Authors <Symfony2-coding-standard@escapestudios.github.com>
* @license http://spdx.org/licenses/MIT MIT License
* @link https://github.com/escapestudios/Symfony2-coding-standard
*/
class BlankLineBeforeReturnSniff implements Sniff
{
/**
* A list of tokenizers this sniff supports.
*
* @var array
*/
public $supportedTokenizers = [
'PHP',
'JS',
];
/**
* {@inheritDoc}
*/
public function register()
{
return [T_RETURN];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$current = $stackPtr;
$previousLine = $tokens[$stackPtr]['line'] - 1;
$prevLineTokens = [];
while ($current >= 0 && $tokens[$current]['line'] >= $previousLine) {
if (
$tokens[$current]['line'] == $previousLine
&& $tokens[$current]['type'] !== 'T_WHITESPACE'
&& $tokens[$current]['type'] !== 'T_COMMENT'
&& $tokens[$current]['type'] !== 'T_DOC_COMMENT_OPEN_TAG'
&& $tokens[$current]['type'] !== 'T_DOC_COMMENT_TAG'
&& $tokens[$current]['type'] !== 'T_DOC_COMMENT_STRING'
&& $tokens[$current]['type'] !== 'T_DOC_COMMENT_CLOSE_TAG'
&& $tokens[$current]['type'] !== 'T_DOC_COMMENT_WHITESPACE'
) {
$prevLineTokens[] = $tokens[$current]['type'];
}
$current--;
}
if (
isset($prevLineTokens[0])
&& ($prevLineTokens[0] === 'T_OPEN_CURLY_BRACKET'
|| $prevLineTokens[0] === 'T_COLON'
|| $prevLineTokens[0] === 'T_OPEN_TAG')
) {
return;
} elseif (count($prevLineTokens) > 0) {
$fix = $phpcsFile->addFixableError(
'Missing blank line before return statement',
$stackPtr,
'BlankLineBeforeReturn'
);
if ($fix === true) {
$phpcsFile->fixer->beginChangeset();
$phpcsFile->fixer->addNewlineBefore($stackPtr - 1);
$phpcsFile->fixer->endChangeset();
}
}
}
}
@@ -0,0 +1,154 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @since CakePHP CodeSniffer 0.1.10
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\Formatting;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
/**
* Ensures all the use are in alphabetical order.
*
*/
class UseInAlphabeticalOrderSniff implements Sniff
{
/**
* Processed files
*
* @var array
*/
protected $_processed = [];
/**
* The list of use statements, their content and scope.
*
* @var array
*/
protected $_uses = [];
/**
* {@inheritDoc}
*/
public function register()
{
return [T_USE];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
if (isset($this->_processed[$phpcsFile->getFilename()])) {
return;
}
$filename = $phpcsFile->getFilename();
$this->_uses = [];
$next = $stackPtr;
while ($next !== false) {
$this->_checkUseToken($phpcsFile, $next);
$next = $phpcsFile->findNext(T_USE, $next + 1);
}
// Prevent multiple uses in the same file from entering
$this->_processed[$phpcsFile->getFilename()] = true;
foreach ($this->_uses as $scope => $used) {
$defined = $sorted = array_keys($used);
natcasesort($sorted);
$sorted = array_values($sorted);
if ($sorted === $defined) {
continue;
}
foreach ($defined as $i => $name) {
if ($name !== $sorted[$i]) {
$error = 'Use classes must be in alphabetical order. Was expecting ' . $sorted[$i];
$phpcsFile->addError($error, $used[$name], 'UseInAlphabeticalOrder');
}
}
}
}
/**
* Check all the use tokens in a file.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file to check.
* @param int $stackPtr The index of the first use token.
* @return void
*/
protected function _checkUseToken($phpcsFile, $stackPtr)
{
// If the use token is for a closure we want to ignore it.
$isClosure = $this->_isClosure($phpcsFile, $stackPtr);
if ($isClosure) {
return;
}
$tokens = $phpcsFile->getTokens();
$scope = 'use';
$useType = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
if ($useType !== false && $tokens[$useType]['code'] === T_STRING) {
$useContent = strtolower($tokens[$useType]['content']);
if ($useContent === 'function' || $useContent === 'const') {
$scope .= ' ' . $useContent;
$stackPtr = $useType + 1;
}
}
$content = '';
$end = $phpcsFile->findNext([T_SEMICOLON, T_OPEN_CURLY_BRACKET], $stackPtr);
$useTokens = array_slice($tokens, $stackPtr, $end - $stackPtr, true);
foreach ($useTokens as $index => $token) {
if ($token['code'] === T_STRING || $token['code'] === T_NS_SEPARATOR) {
$content .= $token['content'];
}
}
// Check for class scoping on use. Traits should be
// ordered independently.
if (!empty($token['conditions'])) {
$scope .= key($token['conditions']);
}
$this->_uses[$scope][$content] = $stackPtr;
}
/**
* Check if the current stackPtr is a use token that is for a closure.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The index of the first use token.
* @return bool
*/
protected function _isClosure($phpcsFile, $stackPtr)
{
return $phpcsFile->findPrevious(
[T_CLOSURE],
($stackPtr - 1),
null,
false,
null,
true
);
}
}
@@ -0,0 +1,54 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.28
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\Functions;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
/**
* Ensures there is a space after the function keyword for closures.
*
*/
class ClosureDeclarationSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_CLOSURE];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$spaces = 0;
if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) {
$spaces = strlen($tokens[($stackPtr + 1)]['content']);
}
if ($spaces !== 1) {
$error = 'Expected 1 space after closure\'s function keyword; %s found';
$data = [$spaces];
$phpcsFile->addError($error, $stackPtr, 'SpaceAfterFunction', $data);
}
}
}
@@ -0,0 +1,34 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.18
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\Functions;
use PHP_CodeSniffer\Standards\Squiz\Sniffs\Functions\FunctionDeclarationArgumentSpacingSniff as SquizFunctionDeclarationArgumentSpacingSniff;
/**
* Ensures the spacing of function declaration arguments is correct.
*
*/
class FunctionDeclarationArgumentSpacingSniff extends SquizFunctionDeclarationArgumentSpacingSniff
{
/**
* How many spaces should surround the equals signs.
*
* @var int
*/
public $equalsSpacing = 1;
}
@@ -0,0 +1,98 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.1
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Ensures method names are correct depending on whether they are public
* or private, and that functions are named correctly.
*
*/
namespace CakePHP\Sniffs\NamingConventions;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\AbstractScopeSniff;
class ValidFunctionNameSniff extends AbstractScopeSniff
{
/**
* A list of all PHP magic methods.
*
* @var array
*/
protected $_magicMethods = [
'construct',
'destruct',
'call',
'callStatic',
'debugInfo',
'get',
'set',
'isset',
'unset',
'sleep',
'wakeup',
'toString',
'set_state',
'clone',
'invoke',
];
/**
* {@inheritDoc}
*/
public function __construct()
{
parent::__construct([T_CLASS, T_INTERFACE, T_TRAIT], [T_FUNCTION], true);
}
/**
* {@inheritDoc}
*/
protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
{
$methodName = $phpcsFile->getDeclarationName($stackPtr);
$className = $phpcsFile->getDeclarationName($currScope);
$errorData = [$className . '::' . $methodName];
// Ignore magic methods
if (preg_match('/^__(' . implode('|', $this->_magicMethods) . ')$/', $methodName)) {
return;
}
$methodProps = $phpcsFile->getMethodProperties($stackPtr);
if ($methodProps['scope_specified'] === false) {
// Let another sniffer take care of that
return;
}
$isPublic = $methodProps['scope'] === 'public';
if ($isPublic === true && $methodName[0] === '_') {
$error = 'Public method name "%s" must not be prefixed with underscore';
$phpcsFile->addError($error, $stackPtr, 'PublicWithUnderscore', $errorData);
return;
}
}
/**
* {@inheritDoc}
*/
protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
{
}
}
@@ -0,0 +1,51 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.10
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Ensures trait names are correct depending on the folder of the file.
*
*/
namespace CakePHP\Sniffs\NamingConventions;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class ValidTraitNameSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_TRAIT];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$traitName = $tokens[$stackPtr + 2]['content'];
if (substr($traitName, -5) !== 'Trait') {
$error = 'Traits must have a "Trait" suffix.';
$phpcsFile->addError($error, $stackPtr, 'InvalidTraitName');
}
}
}
@@ -0,0 +1,73 @@
<?php
namespace CakePHP\Sniffs\PHP;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
/**
* Adds trailing commas in multiline arrays.
*
* Heredoc patch taken from slevomat/coding-standard project.
*
* @author Mark Scherer
* @license MIT
*/
class CommaAfterArrayItemSniff implements Sniff
{
/**
* @var bool
*/
public $enableAfterHeredoc = PHP_VERSION_ID >= 70300;
/**
* @inheritDoc
*/
public function register()
{
return [
T_OPEN_SHORT_ARRAY,
];
}
/**
* @inheritDoc
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$arrayToken = $tokens[$stackPtr];
$closeParenthesisPointer = $arrayToken['bracket_closer'];
$openParenthesisToken = $tokens[$arrayToken['bracket_opener']];
$closeParenthesisToken = $tokens[$closeParenthesisPointer];
if ($openParenthesisToken['line'] === $closeParenthesisToken['line']) {
return;
}
$previousToCloseParenthesisPointer = $phpcsFile->findPrevious(Tokens::$emptyTokens, $closeParenthesisPointer - 1, 0, true);
$previousToCloseParenthesisToken = $tokens[$previousToCloseParenthesisPointer];
if (
$previousToCloseParenthesisPointer === $arrayToken['bracket_opener']
|| $previousToCloseParenthesisToken['code'] === T_COMMA
|| $closeParenthesisToken['line'] === $previousToCloseParenthesisToken['line']
) {
return;
}
if (!$this->enableAfterHeredoc && in_array($previousToCloseParenthesisToken['code'], [T_END_HEREDOC, T_END_NOWDOC], true)) {
return;
}
$fix = $phpcsFile->addFixableError(
'Multi-line arrays must have a trailing comma after the last element.',
$previousToCloseParenthesisPointer,
'MissingTrailingComma'
);
if (!$fix) {
return;
}
$phpcsFile->fixer->beginChangeset();
$phpcsFile->fixer->addContent($previousToCloseParenthesisPointer, ',');
$phpcsFile->fixer->endChangeset();
}
}
@@ -0,0 +1,62 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.14
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Disallow short open tags
*
* But permit short-open echo tags (<?=) [T_OPEN_TAG_WITH_ECHO] as they are part of PHP 5.4+
*
*/
namespace CakePHP\Sniffs\PHP;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class DisallowShortOpenTagSniff implements Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* If short open tags are NOT enabled, <? is not considered a T_OPEN_TAG
* So include T_INLINE_HTML which is what "<?" is detected as
*
* @return array
*/
public function register()
{
return [
T_OPEN_TAG,
T_INLINE_HTML,
];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$openTag = $tokens[$stackPtr];
if (trim($openTag['content']) === '<?') {
$error = 'Short PHP opening tag used; expected "<?php" but found "%s"';
$data = [trim($openTag['content'])];
$phpcsFile->addError($error, $stackPtr, 'Found', $data);
}
}
}
@@ -0,0 +1,86 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Asserts that type casts are in the short form:
* - bool instead of boolean
* - int instead of integer
*/
namespace CakePHP\Sniffs\PHP;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
class TypeCastingSniff implements Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* Note, that this sniff only checks the value and casing of a cast.
* It does not check for whitespace issues regarding casts, as
* - Squiz.WhiteSpace.CastSpacing.ContainsWhiteSpace checks for whitespace in the cast
* - Generic.Formatting.NoSpaceAfterCast.SpaceFound checks for whitespace after the cast
*
* @return array
*/
public function register()
{
return array_merge(Tokens::$castTokens, [T_BOOLEAN_NOT]);
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
// Process !! casts
if ($tokens[$stackPtr]['code'] == T_BOOLEAN_NOT) {
$nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if (!$nextToken) {
return;
}
if ($tokens[$nextToken]['code'] != T_BOOLEAN_NOT) {
return;
}
$error = 'Usage of !! cast is not allowed. Please use (bool) to cast.';
$phpcsFile->addError($error, $stackPtr, 'NotAllowed');
return;
}
// Only allow short forms if both short and long forms are possible
$matching = [
'(boolean)' => '(bool)',
'(integer)' => '(int)',
];
$content = $tokens[$stackPtr]['content'];
$key = strtolower($content);
if (isset($matching[$key])) {
$error = 'Please use ' . $matching[$key] . ' instead of ' . $content . '.';
$phpcsFile->addError($error, $stackPtr, 'NotAllowed');
return;
}
if ($content !== $key) {
$error = 'Please use ' . $key . ' instead of ' . $content . '.';
$phpcsFile->addError($error, $stackPtr, 'NotAllowed');
return;
}
}
}
@@ -0,0 +1,71 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.1
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Makes sure there are spaces between the concatenation operator (.) and
* the strings being concatenated.
*
*/
namespace CakePHP\Sniffs\Strings;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class ConcatenationSpacingSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_STRING_CONCAT];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) {
$message = 'Expected 1 space before ., but 0 found';
$phpcsFile->addError($message, $stackPtr, 'MissingBefore');
} else {
$content = str_replace("\r\n", "\n", $tokens[($stackPtr - 1)]['content']);
$spaces = strlen($content);
if ($spaces > 1) {
$message = 'Expected 1 space before ., but %d found';
$data = [$spaces];
$phpcsFile->addError($message, $stackPtr, 'TooManyBefore', $data);
}
}
if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) {
$message = 'Expected 1 space after ., but 0 found';
$phpcsFile->addError($message, $stackPtr, 'MissingAfter');
} else {
$content = str_replace("\r\n", "\n", $tokens[($stackPtr + 1)]['content']);
$spaces = strlen($content);
if ($spaces > 1) {
$message = 'Expected 1 space after ., but %d found';
$data = [$spaces];
$phpcsFile->addError($message, $stackPtr, 'TooManyAfter', $data);
}
}
}
}
@@ -0,0 +1,72 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.14
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Ensures no whitespaces and one whitespace is placed around each comma
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class CommaSpacingSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_COMMA];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
if ($tokens[$next]['code'] !== T_WHITESPACE && ($next !== $stackPtr + 2)) {
// Skip if immediate char is comma
if ($tokens[$next]['code'] === T_COMMA) {
return;
}
// Last character in a line is ok.
if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) {
$error = 'Missing space after comma';
$fix = $phpcsFile->addFixableError($error, $next, 'MissingSpaceAfterComma');
if ($fix === true) {
$phpcsFile->fixer->beginChangeset();
$phpcsFile->fixer->addContent($stackPtr, ' ');
$phpcsFile->fixer->endChangeset();
}
}
}
$previous = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
if ($tokens[$previous]['code'] !== T_WHITESPACE && ($previous !== $stackPtr - 1)) {
$error = 'Space before comma, expected none, though';
$phpcsFile->addError($error, $next, 'SpaceBeforeComma');
}
}
}
@@ -0,0 +1,62 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 2.4.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Ensures that not more than one blank line occurs
*
* @author Mark Scherer
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class EmptyLinesSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_WHITESPACE];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
// If the current and next two tokens are newlines
// We can remove the next token (the first newline)
if (
$tokens[$stackPtr]['content'] === $phpcsFile->eolChar
&& isset($tokens[$stackPtr + 1])
&& $tokens[$stackPtr + 1]['content'] === $phpcsFile->eolChar
&& isset($tokens[$stackPtr + 2])
&& $tokens[$stackPtr + 2]['content'] === $phpcsFile->eolChar
) {
$error = 'Found more than a single empty line between content';
$fix = $phpcsFile->addFixableError($error, $stackPtr + 2, 'EmptyLines');
if ($fix) {
$phpcsFile->fixer->replaceToken($stackPtr + 2, '');
}
}
}
}
@@ -0,0 +1,68 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.12
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Checks the separation between methods in a class or interface.
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
class FunctionCallSpacingSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [
T_ISSET,
T_EMPTY,
T_STRING,
T_INCLUDE,
T_INCLUDE_ONCE,
T_REQUIRE,
T_REQUIRE_ONCE,
];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
// Find the next non-empty token.
$openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
// Not a function call.
return;
}
// Look for funcName (
if (($stackPtr + 1) !== $openBracket) {
$error = 'Space before opening parenthesis of function call not allowed';
$phpcsFile->addError($error, $stackPtr, 'SpaceBeforeOpenBracket');
}
}
}
@@ -0,0 +1,74 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* This file is originally written by Greg Sherwood and Marc McIntyre, but
* modified for CakePHP.
*
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.1
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
/**
* Checks that there is one empty line before the closing brace of a function.
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class FunctionClosingBraceSpaceSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_FUNCTION];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if (isset($tokens[$stackPtr]['scope_closer']) === false) {
// Probably an interface method.
return;
}
$closeBrace = $tokens[$stackPtr]['scope_closer'];
$prevContent = $phpcsFile->findPrevious(T_WHITESPACE, ($closeBrace - 1), null, true);
$braceLine = $tokens[$closeBrace]['line'];
$prevLine = $tokens[$prevContent]['line'];
$found = ($braceLine - $prevLine - 1);
if ($phpcsFile->hasCondition($stackPtr, T_FUNCTION) === true || isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
// Nested function.
if ($found < 0) {
$error = 'Closing brace of nested function must be on a new line';
$phpcsFile->addError($error, $closeBrace, 'ContentBeforeClose');
} elseif ($found > 0) {
$error = 'Expected 0 blank lines before closing brace of nested function; %s found';
$data = [$found];
$phpcsFile->addError($error, $closeBrace, 'SpacingBeforeNestedClose', $data);
}
} else {
if ($found !== 0) {
$error = 'Expected 0 blank lines before closing function brace; %s found';
$data = [$found];
$phpcsFile->addError($error, $closeBrace, 'SpacingBeforeClose', $data);
}
}
}
}
@@ -0,0 +1,68 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* This file is originally written by Greg Sherwood and Marc McIntyre, but
* modified for CakePHP.
*
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.1
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
/**
* Checks that there is no empty line after the opening brace of a function.
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class FunctionOpeningBraceSpaceSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_FUNCTION];
}
/**
* {@inheritDoc}
*/
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 = [$found];
$phpcsFile->addError($error, $openBrace, 'SpacingAfter', $data);
}
}
}
@@ -0,0 +1,154 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* This file is originally written by Greg Sherwood and Marc McIntyre, but
* modified for CakePHP.
*
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @link https://github.com/cakephp/cakephp-codesniffer
* @since CakePHP CodeSniffer 0.1.1
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
/**
* Checks the separation between methods in a class or interface.
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
/**
* There should always be newlines around functions/methods.
*/
class FunctionSpacingSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_FUNCTION];
}
/**
* {@inheritDoc}
*/
public function process(File $phpCsFile, $stackPointer)
{
$tokens = $phpCsFile->getTokens();
$level = $tokens[$stackPointer]['level'];
if ($level < 1) {
return;
}
$openingBraceIndex = $phpCsFile->findNext(T_OPEN_CURLY_BRACKET, $stackPointer + 1);
// Fix interface methods
if (!$openingBraceIndex) {
$openingParenthesisIndex = $phpCsFile->findNext(T_OPEN_PARENTHESIS, $stackPointer + 1);
$closingParenthesisIndex = $tokens[$openingParenthesisIndex]['parenthesis_closer'];
$semicolonIndex = $phpCsFile->findNext(T_SEMICOLON, $closingParenthesisIndex + 1);
$nextContentIndex = $phpCsFile->findNext(T_WHITESPACE, $semicolonIndex + 1, null, true);
// Do not mess with the end of the class
if ($tokens[$nextContentIndex]['type'] === 'T_CLOSE_CURLY_BRACKET') {
return;
}
if ($tokens[$nextContentIndex]['line'] - $tokens[$semicolonIndex]['line'] <= 1) {
$fix = $phpCsFile->addFixableError('Every function/method needs a newline afterwards', $closingParenthesisIndex, 'Abstract');
if ($fix) {
$phpCsFile->fixer->addNewline($semicolonIndex);
}
}
return;
}
$closingBraceIndex = $tokens[$openingBraceIndex]['scope_closer'];
// Ignore closures
$nextIndex = $phpCsFile->findNext(Tokens::$emptyTokens, $closingBraceIndex + 1, null, true);
if (in_array($tokens[$nextIndex]['content'], [';', ',', ')'])) {
return;
}
$nextContentIndex = $phpCsFile->findNext(T_WHITESPACE, $closingBraceIndex + 1, null, true);
// Do not mess with the end of the class
if ($tokens[$nextContentIndex]['type'] === 'T_CLOSE_CURLY_BRACKET') {
return;
}
$this->assertNewLineAtTheEnd($phpCsFile, $closingBraceIndex, $nextContentIndex);
$this->assertNewLineAtTheBeginning($phpCsFile, $stackPointer);
}
/**
* @param \PHP_CodeSniffer\Files\File $phpCsFile File
* @param int $closingBraceIndex Index
* @param int|null $nextContentIndex Index
*
* @return void
*/
protected function assertNewLineAtTheEnd(File $phpCsFile, $closingBraceIndex, $nextContentIndex)
{
$tokens = $phpCsFile->getTokens();
if (!$nextContentIndex || $tokens[$nextContentIndex]['line'] - $tokens[$closingBraceIndex]['line'] <= 1) {
$fix = $phpCsFile->addFixableError('Every function/method needs a newline afterwards', $closingBraceIndex, 'Concrete');
if ($fix) {
$phpCsFile->fixer->addNewline($closingBraceIndex);
}
}
}
/**
* Asserts newline at the beginning, including the doc block.
*
* @param \PHP_CodeSniffer\Files\File $phpCsFile File
* @param int $stackPointer Stack pointer
*
* @return void
*/
protected function assertNewLineAtTheBeginning(File $phpCsFile, $stackPointer)
{
$tokens = $phpCsFile->getTokens();
$line = $tokens[$stackPointer]['line'];
$firstTokenInLineIndex = $stackPointer;
while ($tokens[$firstTokenInLineIndex - 1]['line'] === $line) {
$firstTokenInLineIndex--;
}
$prevContentIndex = $phpCsFile->findPrevious(T_WHITESPACE, $firstTokenInLineIndex - 1, null, true);
if ($tokens[$prevContentIndex]['type'] === 'T_DOC_COMMENT_CLOSE_TAG') {
$firstTokenInLineIndex = $tokens[$prevContentIndex]['comment_opener'];
while ($tokens[$firstTokenInLineIndex - 1]['line'] === $line) {
$firstTokenInLineIndex--;
}
}
$prevContentIndex = $phpCsFile->findPrevious(T_WHITESPACE, $firstTokenInLineIndex - 1, null, true);
// Do not mess with the start of the class
if ($tokens[$prevContentIndex]['type'] === 'T_OPEN_CURLY_BRACKET') {
return;
}
if ($tokens[$prevContentIndex]['line'] < $tokens[$firstTokenInLineIndex]['line'] - 1) {
return;
}
$fix = $phpCsFile->addFixableError('Every function/method needs a newline before', $firstTokenInLineIndex, 'Concrete');
if ($fix) {
$phpCsFile->fixer->addNewline($prevContentIndex);
}
}
}
@@ -0,0 +1,50 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* This file is originally written by Greg Sherwood and Marc McIntyre, but
* modified for CakePHP.
*
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.1
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
/**
* Ensure there is no whitespace after an object operator.
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
class ObjectOperatorSpacingSniff implements Sniff
{
/**
* {@inheritDoc}
*/
public function register()
{
return [T_OBJECT_OPERATOR];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$nextType = $tokens[($stackPtr + 1)]['code'];
if (in_array($nextType, Tokens::$emptyTokens) === true) {
$error = 'Space found after object operator';
$phpcsFile->addError($error, $stackPtr, 'After');
}
}
}
@@ -0,0 +1,208 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* This file is originally written by Greg Sherwood and Marc McIntyre, but
* modified for CakePHP.
*
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.6
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
/**
* Verifies that operators have valid spacing surrounding them.
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
class OperatorSpacingSniff implements Sniff
{
/**
* A list of tokenizers this sniff supports.
*
* @var array
*/
public $supportedTokenizers = [
'PHP',
'JS',
];
/**
* {@inheritDoc}
*/
public function register()
{
$comparison = Tokens::$comparisonTokens;
$operators = Tokens::$operators;
$assignment = Tokens::$assignmentTokens;
return array_unique(array_merge($comparison, $operators, $assignment));
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
// Skip default values in function declarations.
// and declare statements
if (
$tokens[$stackPtr]['code'] === T_EQUAL
|| $tokens[$stackPtr]['code'] === T_MINUS
) {
if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
$parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
$bracket = array_pop($parenthesis);
if (isset($tokens[$bracket]['parenthesis_owner']) === true) {
$function = $tokens[$bracket]['parenthesis_owner'];
if (
$tokens[$function]['code'] === T_FUNCTION ||
$tokens[$function]['code'] === T_DECLARE
) {
return;
}
}
}
}
if ($tokens[$stackPtr]['code'] === T_EQUAL) {
// Skip for '=&' case.
if (isset($tokens[($stackPtr + 1)]) === true && $tokens[($stackPtr + 1)]['code'] === T_BITWISE_AND) {
return;
}
}
if ($tokens[$stackPtr]['code'] === T_BITWISE_AND) {
// If its not a reference, then we expect one space either side of the
// bitwise operator.
if (!$phpcsFile->isReference($stackPtr) && !$this->_isVariable($stackPtr, $tokens, $phpcsFile)) {
// Check there is one space before the & operator.
if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) {
$error = 'Expected 1 space before "&" operator; 0 found';
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceBeforeAmp');
if ($fix === true) {
$phpcsFile->fixer->addContentBefore($stackPtr, ' ');
}
}
// Check there is one space after the & operator.
if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) {
$error = 'Expected 1 space after "&" operator; 0 found';
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfterAmp');
if ($fix === true) {
$phpcsFile->fixer->addContent($stackPtr, ' ');
}
}
}
} else {
if ($tokens[$stackPtr]['code'] === T_MINUS) {
// Skip declaration of negative value in new array format; eg. $arr = [-1].
if ($tokens[($stackPtr - 1)]['code'] === T_OPEN_SHORT_ARRAY) {
return;
}
// Check minus spacing, but make sure we aren't just assigning
// a minus value or returning one.
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
if ($tokens[$prev]['code'] === T_RETURN) {
// Just returning a negative value; eg. return -1.
return;
}
if (in_array($tokens[$prev]['code'], Tokens::$operators) === true) {
// Just trying to operate on a negative value; eg. ($var * -1).
return;
}
if (in_array($tokens[$prev]['code'], Tokens::$comparisonTokens) === true) {
// Just trying to compare a negative value; eg. ($var === -1).
return;
}
// A list of tokens that indicate that the token is not
// part of an arithmetic operation.
$invalidTokens = [
T_COMMA,
T_OPEN_PARENTHESIS,
T_OPEN_SQUARE_BRACKET,
T_DOUBLE_ARROW,
T_COLON,
T_INLINE_THEN,
T_INLINE_ELSE,
T_CASE,
];
if (in_array($tokens[$prev]['code'], $invalidTokens) === true) {
// Just trying to use a negative value; eg. myFunction($var, -2).
return;
}
if (in_array($tokens[$prev]['code'], Tokens::$assignmentTokens) === true) {
// Just trying to assign a negative value; eg. ($var = -1).
return;
}
}
$operator = $tokens[$stackPtr]['content'];
if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) {
$error = "Expected 1 space before \"$operator\"; 0 found";
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceBefore');
if ($fix === true) {
$phpcsFile->fixer->addContentBefore($stackPtr, ' ');
}
}
if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) {
$error = "Expected 1 space after \"$operator\"; 0 found";
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfter');
if ($fix === true) {
$phpcsFile->fixer->addContent($stackPtr, ' ');
}
}
}
}
/**
* Check if the current token is inside an array.
*
* @param int $stackPtr The current token offset.
* @param array $tokens The current token list.
* @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being checked.
* @return bool
*/
protected function _isVariable($stackPtr, $tokens, $phpcsFile)
{
$tokenAfter = $phpcsFile->findNext(
Tokens::$emptyTokens,
($stackPtr + 1),
null,
true
);
$tokenBefore = $phpcsFile->findNext(
Tokens::$emptyTokens,
($stackPtr - 1),
null,
true
);
return ($tokens[$tokenAfter]['code'] === T_VARIABLE &&
(
$tokens[$tokenBefore]['code'] === T_OPEN_PARENTHESIS ||
$tokens[$tokenBefore]['code'] === T_COMMA ||
$tokens[$tokenBefore]['code'] === T_OPEN_SHORT_ARRAY
)
);
}
}
@@ -0,0 +1,75 @@
<?php
/**
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://pear.php.net/package/PHP_CodeSniffer_CakePHP
* @since CakePHP CodeSniffer 0.1.11
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* Check for any line starting with 2 spaces - which would indicate space indenting
* Also check for "\t " - a tab followed by a space, which is a common similar mistake
*
*/
namespace CakePHP\Sniffs\WhiteSpace;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
class TabAndSpaceSniff implements Sniff
{
/**
* A list of tokenizers this sniff supports.
*
* @var array
*/
public $supportedTokenizers = [
'PHP',
'JS',
'CSS',
];
/**
* {@inheritDoc}
*/
public function register()
{
return [T_WHITESPACE];
}
/**
* {@inheritDoc}
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$line = $tokens[$stackPtr]['line'];
if ($stackPtr > 0 && $tokens[($stackPtr - 1)]['line'] !== $line) {
return;
}
if (strpos($tokens[$stackPtr]['content'], ' ') !== false) {
$error = 'Double space found';
$phpcsFile->addError($error, $stackPtr, 'DoubleSpace');
}
if (strpos($tokens[$stackPtr]['content'], " \t") !== false) {
$error = 'Space and tab found';
$phpcsFile->addError($error, $stackPtr, 'SpaceAndTab');
}
if (strpos($tokens[$stackPtr]['content'], "\t ") !== false) {
$error = 'Tab and space found';
$phpcsFile->addError($error, $stackPtr, 'TabAndSpace');
}
}
}
@@ -0,0 +1,34 @@
<?php
/**
* Tell me what worries you.
*/
namespace App\Person\Patient;
/**
* Hello World.
*
* This is a description.
*/
class Foo extends Bar
{
/**
* What are your thoughts?
*
* @var array $brain
*/
public $brain = [];
/**
* Tell me your thoughts.
*
* @return void
*/
public function dumpThoughts($thoughts)
{
/** @var array $thoughts */
foreach ($thoughts as $thought) {
/** @var string $thought */
echo $thought;
}
}
}
@@ -0,0 +1,34 @@
<?php
/**
* Tell me what worries you.
*/
namespace App\Person\Patient;
/**
* Hello World.
*
* This is a description.
*/
class Foo extends Bar
{
/**
* What are your thoughts?
*
* @var array $brain
*/
public $brain = [];
/**
* Tell me your thoughts.
*
* @return void
*/
public function dumpThoughts($thoughts)
{
/** @var array $thoughts */
foreach ($thoughts as $thought) {
/** @var string $thought */
echo $thought;
}
}
}
@@ -0,0 +1,24 @@
<?php
/**
* Hello World.
*
* This is a description.
*/
$things = 'fun';
/**
* I'm static.
*/
Foo::bar($things);
$anotherThing = 'what';
/**
* What happens with If's?
*
*/
if ($anotherThing !== 'notfun') {
$anotherThing = 'Oh no.';
}
$hello = 'world';
@@ -0,0 +1,29 @@
<?php
namespace Cake;
/**
* Hello World.
*
* This is a description.
*/
class Foo extends Bar
{
/**
* What are your thoughts?
*
* @var array $brain
*/
public $brain = array();
/**
* Tell me your thoughts.
*
* @return void
*/
public function dumpThoughts()
{
foreach ($thoughts as $thought) {
echo $thought;
}
}
}
@@ -0,0 +1,36 @@
<?php
namespace CakePHP\Tests\Commenting;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class DocBlockAlignmentUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList($testFile = '')
{
switch ($testFile) {
case 'DocBlockAlignmentUnitTest.1.inc':
return [
2 => 1,
7 => 1,
14 => 1,
21 => 1,
30 => 1,
];
default:
return [];
}
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,251 @@
<?php
namespace Beakman;
use Other\Crap;
use Other\Error as OtherError;
class Foo
{
/**
* Some sentence.
*
* @param integer $param Some Param.
* @param boolean $otherParam Some Other Param.
* @return string Something.
*/
public function bar($param, $otherParam)
{
}
/**
* Some sentence.
*
* @param int $param
* @param bool $otherParam
* @return void
*/
public function missingParamComment($param, $otherParam)
{
}
/**
* Some sentence.
*
* @param
* @param
* @return void
*/
public function missingParamType($param, $otherParam)
{
}
/**
* Some sentence.
*
* @return void
*/
public function invalidReturnVoid()
{
return 'string';
}
/**
* [doThing description]
*
* @param string $foo Foo foo foo.
* @return void
*/
public function doThing($foo)
{
}
/**
* Test throws
*
* @throws Exception An expection happened.
* @throws CakePHP\Boom A boom went off.
* @throws CakePHP\Error\Boom Oh, shucks, another boom.
* @throws Other\Crap Oh boy.
* @throws Other\Error\Issue A missing tissue for your PSR-2 issues.
* @return void
*/
public function test()
{
switch ($a) {
case 1:
throw new Boom();
case 2:
throw new Error\Boom();
case 3:
throw new OtherError\Issue();
case 4:
throw new Crap();
default:
throw new \Exception();
}
}
/**
* @return void
* @return void
*/
public function doubleReturn()
{
}
/**
* @return
*/
public function missingReturnType()
{
}
/**
* @return integer
*/
public function returnIntegerFail()
{
return 1;
}
/**
* @return boolean
*/
public function returnBooleanFail()
{
return false;
}
/**
* @return int
*/
public function returnIntPass()
{
return 1;
}
/**
* @return bool
*/
public function returnBooleanPass()
{
return false;
}
/**
* @return int
*/
public function invalidReturnNotVoid()
{
return;
}
/**
* @return void
* @throws
*/
public function invalidThrows()
{
throw new \RuntimeException();
return;
}
/**
* @return void
* @throws \RuntimeException()
*/
public function EmptyThrows()
{
throw new \RuntimeException();
return;
}
/**
* @return void
* @throws \RuntimeException No dot
*/
public function throwsNoFullStop()
{
throw new \RuntimeException();
}
/**
* @return void
* @throws \RuntimeException not a capital.
*/
public function throwsNotCapital()
{
throw new \RuntimeException();
}
/**
* @param int $param not a capital.
* @return void
*/
public function paramCommentNotCapital($param)
{
}
/**
* @param int $param No final dot
* @return void
*/
public function paramCommentFullStop($param)
{
}
/**
* @param int $para Comment.
* @return void
*/
public function paramNameNoMatch($param)
{
}
/**
* @param int $Param Comment.
* @return void
*/
public function paramNameNoCaseMatch($param)
{
}
/**
*
*/
public function missingReturn()
{
return 'what';
}
/**
* @param int
* @return void
*/
public function missingParamName($param)
{
}
/**
* @param int $param A description.
* @param int $superflous A description.
* @return void
*/
public function extraParamComment($param)
{
}
/**
* {@inheritDoc}
*/
public function inherited()
{
}
/**
* {@inheritdoc}
*/
public function inheritedCaseInsentive()
{
}
}
@@ -0,0 +1,251 @@
<?php
namespace Beakman;
use Other\Crap;
use Other\Error as OtherError;
class Foo
{
/**
* Some sentence.
*
* @param int $param Some Param.
* @param bool $otherParam Some Other Param.
* @return string Something.
*/
public function bar($param, $otherParam)
{
}
/**
* Some sentence.
*
* @param int $param
* @param bool $otherParam
* @return void
*/
public function missingParamComment($param, $otherParam)
{
}
/**
* Some sentence.
*
* @param
* @param
* @return void
*/
public function missingParamType($param, $otherParam)
{
}
/**
* Some sentence.
*
* @return void
*/
public function invalidReturnVoid()
{
return 'string';
}
/**
* [doThing description]
*
* @param string $foo Foo foo foo.
* @return void
*/
public function doThing($foo)
{
}
/**
* Test throws
*
* @throws Exception An expection happened.
* @throws CakePHP\Boom A boom went off.
* @throws CakePHP\Error\Boom Oh, shucks, another boom.
* @throws Other\Crap Oh boy.
* @throws Other\Error\Issue A missing tissue for your PSR-2 issues.
* @return void
*/
public function test()
{
switch ($a) {
case 1:
throw new Boom();
case 2:
throw new Error\Boom();
case 3:
throw new OtherError\Issue();
case 4:
throw new Crap();
default:
throw new \Exception();
}
}
/**
* @return void
* @return void
*/
public function doubleReturn()
{
}
/**
* @return
*/
public function missingReturnType()
{
}
/**
* @return integer
*/
public function returnIntegerFail()
{
return 1;
}
/**
* @return boolean
*/
public function returnBooleanFail()
{
return false;
}
/**
* @return int
*/
public function returnIntPass()
{
return 1;
}
/**
* @return bool
*/
public function returnBooleanPass()
{
return false;
}
/**
* @return int
*/
public function invalidReturnNotVoid()
{
return;
}
/**
* @return void
* @throws
*/
public function invalidThrows()
{
throw new \RuntimeException();
return;
}
/**
* @return void
* @throws \RuntimeException()
*/
public function EmptyThrows()
{
throw new \RuntimeException();
return;
}
/**
* @return void
* @throws \RuntimeException No dot
*/
public function throwsNoFullStop()
{
throw new \RuntimeException();
}
/**
* @return void
* @throws \RuntimeException not a capital.
*/
public function throwsNotCapital()
{
throw new \RuntimeException();
}
/**
* @param int $param not a capital.
* @return void
*/
public function paramCommentNotCapital($param)
{
}
/**
* @param int $param No final dot
* @return void
*/
public function paramCommentFullStop($param)
{
}
/**
* @param int $param Comment.
* @return void
*/
public function paramNameNoMatch($param)
{
}
/**
* @param int $param Comment.
* @return void
*/
public function paramNameNoCaseMatch($param)
{
}
/**
*
*/
public function missingReturn()
{
return 'what';
}
/**
* @param int
* @return void
*/
public function missingParamName($param)
{
}
/**
* @param int $param A description.
* @param int $superflous A description.
* @return void
*/
public function extraParamComment($param)
{
}
/**
* {@inheritDoc}
*/
public function inherited()
{
}
/**
* {@inheritdoc}
*/
public function inheritedCaseInsentive()
{
}
}
@@ -0,0 +1,54 @@
<?php
namespace CakePHP\Tests\Commenting;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class FunctionCommentUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
12 => 1,
13 => 1,
23 => 1,
24 => 1,
34 => 1,
35 => 1,
90 => 1,
97 => 1,
104 => 1,
112 => 1,
222 => 1,
231 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [
14 => 1,
31 => 2,
45 => 1,
140 => 1,
145 => 1,
155 => 1,
165 => 1,
174 => 1,
182 => 1,
190 => 1,
197 => 1,
198 => 1,
205 => 1,
206 => 1,
215 => 1,
221 => 1,
];
}
}
@@ -0,0 +1,14 @@
<?php
for ($i = 0; $i < 10; $i++) {
echo 'hello';
}
if ($i < 10) {
echo 'hello2';
} elseif ($i > 100) {
echo 'i > 100';
}
if($abc == true)
echo 'hello';
@@ -0,0 +1,26 @@
<?php
namespace CakePHP\Tests\ControlStructures;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ControlStructuresUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
13 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,6 @@
<?php
if (isset($a)) {
echo 'a isset';
} else if (isset($b)) {
echo 'b isset';
}
@@ -0,0 +1,26 @@
<?php
namespace CakePHP\Tests\ControlStructures;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ElseIfDeclarationUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
4 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,16 @@
<?php
while (false)
echo 'faiL';
do
echo 'dowhile test';
while (false);
echo 'dowhile test';
} while (false);
while (false) {
echo 'pass';
}
do {
@@ -0,0 +1,27 @@
<?php
namespace CakePHP\Tests\ControlStructures;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class WhileStructuresUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
2 => 1,
5 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,104 @@
<?php
return [
'foo' => 'bar'
];
function invalidFunctionReturnOne()
{
echo "";
return null;
}
function invalidFunctionReturnOne()
{
if(true) {
echo "";
}
return null;
}
/**
* [validFunctionReturnOne description]
*
* @return null
*/
function validFunctionReturnOne()
{
return null;
}
/**
* [validFunctionReturnTwo description]
*
* @return null|bool
*/
function validFunctionReturnTwo()
{
if ($a) {
return true;
}
return null;
}
/**
* [validFunctionReturnThree description]
*
* @return null
*/
function validFunctionReturnThree()
{
echo "";
return null;
}
/**
* [validFunctionReturnFour description]
*
* @return null
*/
function validFunctionReturnFour()
{
// comment
return null;
}
/**
* [validFunctionReturnFive description]
*
* @return null
*/
function validFunctionReturnFive()
{
/**
* multi-line
*/
return null;
}
/**
* [validFunctionReturnSix description]
*
* @return null|bool
*/
function validFunctionReturnSix()
{
switch ($condition) {
case 'foo':
return true;
default:
return false;
}
}
/**
* [validFunctionReturnSeven description]
*
* @return null
*/
function validFunctionReturnSeven()
{
/** @var Foo $foo */
return null;
}
@@ -0,0 +1,106 @@
<?php
return [
'foo' => 'bar'
];
function invalidFunctionReturnOne()
{
echo "";
return null;
}
function invalidFunctionReturnOne()
{
if(true) {
echo "";
}
return null;
}
/**
* [validFunctionReturnOne description]
*
* @return null
*/
function validFunctionReturnOne()
{
return null;
}
/**
* [validFunctionReturnTwo description]
*
* @return null|bool
*/
function validFunctionReturnTwo()
{
if ($a) {
return true;
}
return null;
}
/**
* [validFunctionReturnThree description]
*
* @return null
*/
function validFunctionReturnThree()
{
echo "";
return null;
}
/**
* [validFunctionReturnFour description]
*
* @return null
*/
function validFunctionReturnFour()
{
// comment
return null;
}
/**
* [validFunctionReturnFive description]
*
* @return null
*/
function validFunctionReturnFive()
{
/**
* multi-line
*/
return null;
}
/**
* [validFunctionReturnSix description]
*
* @return null|bool
*/
function validFunctionReturnSix()
{
switch ($condition) {
case 'foo':
return true;
default:
return false;
}
}
/**
* [validFunctionReturnSeven description]
*
* @return null
*/
function validFunctionReturnSeven()
{
/** @var Foo $foo */
return null;
}
@@ -0,0 +1,27 @@
<?php
namespace CakePHP\Tests\Formatting;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class BlankLineBeforeReturnUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
9 => 1,
17 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,10 @@
<?php
use Cake\Routing\Router;
use Cake\Error;
use Cake\Utility\Hash;
class Foo {
use LogTrait;
use FirstTrait;
}
@@ -0,0 +1,12 @@
<?php
namespace BryanCrowe;
use Cake\Routing\RouteCollection;
use Cake\Routing\Router;
use Cake\Routing\Route\Route;
class Foo
{
use FirstTrait;
use LogTrait;
}
@@ -0,0 +1,13 @@
<?php
namespace BryanCrowe;
use Exception;
use RuntimeException;
use function compact;
class Foo
{
use FirstTrait;
use LogTrait;
}
@@ -0,0 +1,35 @@
<?php
namespace CakePHP\Tests\Formatting;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class UseInAlphabeticalOrderUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList($testFile = '')
{
switch ($testFile) {
case 'UseInAlphabeticalOrderUnitTest.1.inc':
return [
3 => 1,
4 => 1,
8 => 1,
9 => 1,
];
default:
return [];
}
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,36 @@
<?php
namespace Beakman;
class TraitUser
{
use FunctionsTrait;
/**
* [doThing description]
*
* @param callable $callback The description.
* @return void
*/
public function doThing(callable $callback)
{
$visitor = function($expression) use (&$visitor, $callback) {
echo 'It fails';
};
$visitor = function ($expression)use(&$visitor, $callback) {
echo 'It works';
};
$visitor($this);
}
}
$foo = 'bar';
$bar = 'foo';
$zum = function()use ($foo, $bar) {
return $foo;
};
$zum = function ()use ($foo, $bar) {
return $foo;
};
@@ -0,0 +1,27 @@
<?php
namespace CakePHP\Tests\Functions;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ClosureDeclarationUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
17 => 1,
30 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,21 @@
<?php
function myFunc( ) {}
function myFunc( $blah ) {}
function myFunc($blah , $blah2, $blah3 ) {}
function myFunc($blah,$blah2,$blah3) {}
function myFunc($blah, $blah2, $blah3) {}
function myFunc($blah='hello') {}
function myFunc( $blah='hello' , $blah2= 'hi', $blah3 = 'yo' ) {}
function myFunc(PHP_CodeSniffer $object, array $array=array(), $blah3='yo') {}
function myFunc( PHP_CodeSniffer $object, array $array=array(), $blah3='yo') {}
function myFunc(PHP_CodeSniffer $object, array $array=array(), $blah3='yo') {}
function myFunc( array &$one, array &$two) {}
function myFunc( &$blah ) {}
function myFunc() {}
function myFunc($blah) {}
function myFunc($blah, $blah2, $blah3) {}
function myFunc($blah = 'hello') {}
function myFunc(&$blah) {}
function myFunc(PHP_CodeSniffer $object, array $array = array(), $blah3 = 'yo') {}
@@ -0,0 +1,37 @@
<?php
namespace CakePHP\Tests\Functions;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class FunctionDeclarationArgumentSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
3 => 1,
4 => 2,
5 => 2,
6 => 2,
7 => 2,
8 => 2,
9 => 9,
10 => 6,
11 => 6,
12 => 4,
13 => 4,
14 => 2,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,177 @@
<?php
namespace Beakman;
class FunctionNames
{
public function _forbidden()
{
echo "I emit an error";
}
private function notDiscouraged()
{
echo "I don't emit a warning anymore";
}
public function setVariables()
{
$this->passingPublic = 'changed';
$this->underscored = 'has value now';
$this->doubleUnderscore = 'not recommended';
}
public static function setStatics()
{
self::$publicStatic = true;
self::$protectedStatic = true;
self::$privateStatic = true;
}
protected function _someFunc()
{
// code here
}
protected function noUnderscorePrefix()
{
// code here
$closure = function () {
// code here
};
}
public function __call($name, $arguments)
{
}
public function __construct()
{
}
public function __clone()
{
}
public function __debugInfo()
{
}
public function __destruct()
{
}
public function __get($name)
{
}
public function __invoke()
{
}
public function __isset($name)
{
}
public function __set($name, $value)
{
}
public function __sleep()
{
}
public function __toString()
{
return '';
}
public function __unset($name)
{
}
public function __wakeup()
{
}
}
interface FunctionNamesInterface
{
public function _forbidden();
public function setVariables();
public static function setStatics();
}
trait FunctionNamesTrait
{
public function _forbidden()
{
echo "I emit an error";
}
private function notDiscouraged()
{
echo "I don't emit a warning anymore";
}
public function setVariables()
{
$this->passingPublic = 'changed';
$this->underscored = 'has value now';
$this->doubleUnderscore = 'not recommended';
}
public static function setStatics()
{
self::$publicStatic = true;
self::$protectedStatic = true;
self::$privateStatic = true;
}
protected function _someFunc()
{
// code here
}
protected function noUnderscorePrefix()
{
// code here
}
function _noScopeSpecified()
{
echo 'handled by an other Sniff';
}
public function __call($name, $arguments)
{
}
public function __construct()
{
}
public function __clone()
{
}
public function __debugInfo()
{
}
public function __destruct()
{
}
public function __get($name)
{
}
public function __invoke()
{
}
public function __isset($name)
{
}
public function __set($name, $value)
{
}
public function __sleep()
{
}
public function __toString()
{
return '';
}
public function __unset($name)
{
}
public function __wakeup()
{
}
}
public function __passingOutside() {}
@@ -0,0 +1,28 @@
<?php
namespace CakePHP\Tests\NamingConventions;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ValidFunctionNameUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
6 => 1,
87 => 1,
96 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,6 @@
<?php
trait Foo {
}
trait WTFTrait {
}
@@ -0,0 +1,26 @@
<?php
namespace CakePHP\Tests\NamingConventions;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ValidTraitNameUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
2 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,9 @@
<?php
/**
* If shortopen tags are not enabled phpcs will report that the file has no php code
* Ensure that there is some php code to skip that logic
*/
$ensure = 'some php code'; ?>
<?
echo "this should fail";
@@ -0,0 +1,26 @@
<?php
namespace CakePHP\Tests\PHP;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class DisallowShortOpenTagUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
8 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,11 @@
<?php
//Fail
$isActive = !!$value;
$isActive = (boolean)$value;
$count = (integer)$someNumber;
$isActive = (Bool)$value;
$count = (Int)$someNumber;
//Pass
$isActive = (bool)$value;
$count = (int)$someNumber;
@@ -0,0 +1,30 @@
<?php
namespace CakePHP\Tests\PHP;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class TypeCastingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
3 => 1,
4 => 1,
5 => 1,
6 => 1,
7 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,10 @@
<?php
$text = 'some' . 'text';
$text = 'some'. 'text';
$text = 'some' .'text';
$text = 'some'.'text';
$text = 'some' . 'text';
$text = 'some' . 'text';
$text = 'some' . 'text';
@@ -0,0 +1,30 @@
<?php
namespace CakePHP\Tests\Strings;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ConcatenationSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
4 => 1,
5 => 1,
6 => 2,
7 => 1,
8 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,5 @@
<?php
echo implode('', array_map('chr', array_map('hexdec',array_filter(explode($delimiter, $string)))));
echo implode('', array_map('chr', array_map('hexdec' , array_filter(explode($delimiter, $string)))));
echo implode('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
list(,, $extension, $filename) = array_values(pathinfo($filename));
@@ -0,0 +1,5 @@
<?php
echo implode('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
echo implode('', array_map('chr', array_map('hexdec' , array_filter(explode($delimiter, $string)))));
echo implode('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
list(,, $extension, $filename) = array_values(pathinfo($filename));
@@ -0,0 +1,27 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class CommaSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
2 => 1,
3 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,49 @@
<?php
namespace Cake;
class MultipleBlankLine
{
public $test;
public $test2;
/**
* [_someFunc description]
*
* @return void
*/
public function myFunction()
{
// code here
}
/**
* [noUnderscorePrefix description]
*
* @return void
*/
public function myFunction2()
{
// code here
}
}
/**
* Description
*
* @return void
*/
function methoWithMultipleBlankLine()
{
echo "1";
echo "2";
}
@@ -0,0 +1,42 @@
<?php
namespace Cake;
class MultipleBlankLine
{
public $test;
public $test2;
/**
* [_someFunc description]
*
* @return void
*/
public function myFunction()
{
// code here
}
/**
* [noUnderscorePrefix description]
*
* @return void
*/
public function myFunction2()
{
// code here
}
}
/**
* Description
*
* @return void
*/
function methoWithMultipleBlankLine()
{
echo "1";
echo "2";
}
@@ -0,0 +1,32 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class EmptyLinesUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
8 => 1,
21 => 1,
42 => 1,
43 => 1,
47 => 1,
48 => 1,
49 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,8 @@
<?php
$noGood = empty ($thing);
$fail = include ('./inline_if_pass.php');
$fail = include_once ('./inline_if_pass.php');
$fail = require ('./inline_if_pass.php');
$fail = require_once ('./inline_if_pass.php');
$o = $obj->something ('testing');
fail_whale ();
@@ -0,0 +1,32 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class FunctionCallSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
2 => 1,
3 => 1,
4 => 1,
5 => 1,
6 => 1,
7 => 1,
8 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,31 @@
<?php
function someFunction(){}
function someFunction()
{}
function greatFunction() {
}
function wrapper () {
return function() {};
}
function somePassingFunction() {
}
function someOtherPassingFunction()
{
}
class Foo
{
public function fail1 {}
public function fail2 {
}
public function fail3 {
echo "fails";}
}
@@ -0,0 +1,31 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class FunctionClosingBraceSpaceUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
3 => 1,
6 => 1,
10 => 1,
25 => 1,
28 => 1,
30 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,10 @@
<?php
function failingFunction() {
echo 'you fail';
}
function somePassingFunction() {
echo 'you pass';
}
@@ -0,0 +1,26 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class FunctionOpeningBraceSpaceUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
3 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,4 @@
<?php
$test-> failling() ;
$test->passing() ;
@@ -0,0 +1,26 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class ObjectOperatorSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
3 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
$ten =10 * 2;
$ten= -10 * 2;
$ten = 10/-2;
$bool = true& true;
$bool = true &true;
$bool = true&true;
$foo = -1;
switch ($foo) {
case -1:
break;
case 'negative':
return -1;
}
$bar = isset($foo) ? -2 : 0;
$foo = isset($bar) ? 0 : -2;
$ten = 10 * 2;
$ten = -10 * 2;
$ten = 10 / -2;
$ten = -10 / 2;
$ten = -10 + 2;
$ten = 10 + -2;
$ten = -10 - 2;
$ten = 10 - -2;
$dec = -0.001;
$dec = -1;
$bool = true & true;
$arr = [-1];
$refArr = [&$foo];
$refArr = [$bar, &$foo];
@@ -0,0 +1,31 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class OperatorSpacingUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
3 => 1,
4 => 1,
5 => 2,
6 => 1,
7 => 1,
8 => 2,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
$ten = 10 * 2;
$ten = -10 * 2;
$ten = 10 / -2;
$bool = true & true;
$bool = true & true;
$bool = true & true;
$foo = -1;
switch ($foo) {
case -1:
break;
case 'negative':
return -1;
}
$bar = isset($foo) ? -2 : 0;
$foo = isset($bar) ? 0 : -2;
$ten = 10 * 2;
$ten = -10 * 2;
$ten = 10 / -2;
$ten = -10 / 2;
$ten = -10 + 2;
$ten = 10 + -2;
$ten = -10 - 2;
$ten = 10 - -2;
$dec = -0.001;
$dec = -1;
$bool = true & true;
$arr = [-1];
$refArr = [&$foo];
$refArr = [$bar, &$foo];
@@ -0,0 +1,3 @@
<?php
$var = 'tab and space';
$var = 'space and tab';
@@ -0,0 +1,27 @@
<?php
namespace CakePHP\Tests\WhiteSpace;
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
class TabAndSpaceUnitTest extends AbstractSniffUnitTest
{
/**
* {@inheritDoc}
*/
public function getErrorList()
{
return [
2 => 1,
3 => 1,
];
}
/**
* {@inheritDoc}
*/
public function getWarningList()
{
return [];
}
}
+181
View File
@@ -0,0 +1,181 @@
<?xml version="1.0"?>
<ruleset name="CakePHP">
<description>CakePHP coding standard</description>
<exclude-pattern>\.git</exclude-pattern>
<exclude-pattern>*/Config/*.ini.php</exclude-pattern>
<exclude-pattern>/*/tmp/</exclude-pattern>
<rule ref="PSR2"/>
<!--
Property and method names with underscore prefix are allowed in CakePHP.
Not using underscore prefix is a recommendation of PSR2, not a requirement.
-->
<rule ref="PSR2.Classes.PropertyDeclaration.Underscore">
<severity>0</severity>
</rule>
<rule ref="PSR2.Methods.MethodDeclaration.Underscore">
<severity>0</severity>
</rule>
<rule ref="Squiz.NamingConventions.ValidFunctionName.PublicUnderscore">
<severity>0</severity>
</rule>
<rule ref="PEAR.NamingConventions.ValidFunctionName.PublicUnderscore">
<severity>0</severity>
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName">
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName.PrivateNoUnderscore">
<severity>0</severity>
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName.ContainsNumbers">
<severity>0</severity>
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName.StringVarContainsNumbers">
<severity>0</severity>
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName.MemberVarContainsNumbers">
<severity>0</severity>
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName.NotCamelCaps">
<severity>0</severity>
</rule>
<rule ref="Zend.NamingConventions.ValidVariableName.MemberVarNotCamelCaps">
<severity>0</severity>
</rule>
<rule ref="PSR12"/>
<rule ref="PSR12.Files.FileHeader.SpacingAfterBlock">
<severity>0</severity>
</rule>
<rule ref="PSR12.Files.FileHeader.IncorrectOrder">
<severity>0</severity>
</rule>
<!--
These are contradictory to PSR12
-->
<rule ref="PSR2.ControlStructures.ControlStructureSpacing.SpacingAfterOpenBrace">
<severity>0</severity>
</rule>
<rule ref="Squiz.ControlStructures.ForLoopDeclaration.SpacingAfterSecond">
<severity>0</severity>
</rule>
<rule ref="Squiz.ControlStructures.ForLoopDeclaration.SpacingAfterFirst">
<severity>0</severity>
</rule>
<!--
These are not applicable for PHP5.6+
-->
<rule ref="PSR12.Properties.ConstantVisibility">
<severity>0</severity>
</rule>
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
<properties>
<property name="ignoreBlankLines" value="false"/>
</properties>
</rule>
<!--
Temporarily ignore until API docblock formatting and line length issues in core code are fixed.
-->
<rule ref="CakePHP.Commenting.FunctionComment"/>
<rule ref="CakePHP.Commenting.FunctionComment.ParamCommentNotCapital">
<severity>0</severity>
</rule>
<rule ref="CakePHP.Commenting.FunctionComment.ParamCommentFullStop">
<severity>0</severity>
</rule>
<rule ref="CakePHP.Commenting.FunctionComment.ThrowsNotCapital">
<severity>0</severity>
</rule>
<rule ref="CakePHP.Commenting.FunctionComment.ThrowsNoFullStop">
<severity>0</severity>
</rule>
<rule ref="CakePHP.Commenting.FunctionComment.EmptyThrows">
<severity>0</severity>
</rule>
<rule ref="Generic.Files.LineLength.TooLong">
<severity>0</severity>
</rule>
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="Squiz.Classes.LowercaseClassKeywords"/>
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
<rule ref="Generic.Commenting.Todo"/>
<rule ref="PEAR.ControlStructures.ControlSignature"/>
<rule ref="Generic.Files.LineEndings"/>
<rule ref="Generic.Formatting.NoSpaceAfterCast"/>
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
<rule ref="Generic.PHP.DeprecatedFunctions"/>
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
<rule ref="Squiz.PHP.Eval"/>
<rule ref="Generic.PHP.ForbiddenFunctions"/>
<rule ref="Squiz.PHP.NonExecutableCode"/>
<rule ref="Generic.PHP.NoSilencedErrors"/>
<rule ref="Squiz.Scope.MemberVarScope"/>
<rule ref="Squiz.Scope.StaticThisUsage"/>
<rule ref="Squiz.WhiteSpace.CastSpacing"/>
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"/>
<rule ref="Squiz.WhiteSpace.ScopeClosingBrace"/>
<rule ref="Generic.NamingConventions.UpperCaseConstantName"/>
<!-- Relax some src/* and tests/* rules -->
<rule ref="PSR1.Files.SideEffects">
<exclude-pattern>*/config/*</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="PSR1.Classes.ClassDeclaration">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="PSR1.Methods.CamelCapsMethodName">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="PEAR.NamingConventions.ValidClassName">
<exclude-pattern>*/CakePHP/*</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="Squiz.Classes.ValidClassName">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="CakePHP.Commenting.FunctionComment">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="Squiz.NamingConventions.ValidFunctionName">
<exclude-pattern>*/src/*</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="Generic.NamingConventions.CamelCapsFunctionName">
<exclude-pattern>*/src/*</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="PEAR.NamingConventions.ValidFunctionName">
<exclude-pattern>*/src/*</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<!-- All rules in ./Sniffs are included automatically -->
</ruleset>
+28
View File
@@ -0,0 +1,28 @@
The MIT License
CakePHP(tm) : The Rapid Development PHP Framework (http://cakephp.org)
Copyright (c) 2005-present, Cake Software Foundation, Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Cake Software Foundation, Inc.
1785 E. Sahara Avenue,
Suite 490-204
Las Vegas, Nevada 89104,
United States of America.
+80
View File
@@ -0,0 +1,80 @@
# CakePHP Code Sniffer
[![Build Status](https://img.shields.io/travis/cakephp/cakephp-codesniffer/master.svg?style=flat-square)](https://travis-ci.org/cakephp/cakephp-codesniffer)
[![Coverage Status](https://img.shields.io/codecov/c/github/cakephp/cakephp-codesniffer.svg?style=flat-square)](https://codecov.io/github/cakephp/cakephp-codesniffer)
[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/cakephp-codesniffer.svg?style=flat-square)](https://packagist.org/packages/cakephp/cakephp-codesniffer)
[![Latest Stable Version](https://img.shields.io/packagist/v/cakephp/cakephp-codesniffer.svg?style=flat-square)](https://packagist.org/packages/cakephp/cakephp-codesniffer)
This code works with [phpcs](http://pear.php.net/manual/en/package.php.php-codesniffer.php)
and checks code against the coding standards used in CakePHP.
:warning: The `master` branch contains codesniffer rules that are based on the
PSR2 standard. If you want to check against the historical CakePHP coding
standard use any of the `1.x` releases.
## Which version should I use?
| Sniffer version | CakePHP version | PHP min |
| -------- | ------- | ------- |
| 1.x | 2.x | PHP 5.4 |
| 2.x | 3.x | PHP 5.5 |
| 3.x | 3.x | PHP 5.6 |
| 4.x | 4.x | PHP 7.1 |
## Installation
You should install this codesniffer with composer:
composer require --dev "cakephp/cakephp-codesniffer"
vendor/bin/phpcs --config-set installed_paths /path/to/your/app/vendor/cakephp/cakephp-codesniffer
The second command lets `phpcs` know where to find your new sniffs. Ensure that
you do not overwrite any existing `installed_paths` value.
## Usage
:warning: Warning when these sniffs are installed with composer, ensure that
you have configured the CodeSniffer `installed_paths` setting.
Depending on how you installed the code sniffer changes how you run it. If you have
installed phpcs, and this package with PEAR, you can do the following:
vendor/bin/phpcs --colors -p -s --standard=CakePHP /path/to/code
You can also copy the `phpcs.xml.dist` file to your project's root folder as `phpcs.xml`.
This file will import the CakePHP Coding Standard. From there you can edit it to
include/exclude as needed. With this file in place, you can run:
vendor/bin/phpcs --colors -p -s /path/to/code
If you are using Composer to manage your CakePHP project, you can also add the below to your composer.json file:
```json
{
"scripts": {
"cs-check": "vendor/bin/phpcs --colors -p -s --extensions=ctp,php ./src ./tests"
}
}
```
## Running Tests
You can run tests with composer. Because of how PHPCS test suites work, there is
additional configuration state in `phpcs` that is required.
```bash
composer test
```
Once this has been done once, you can use `phpunit --filter CakePHP` to run the
tests for the rules in this repository.
## Contributing
If you'd like to contribute to the Code Sniffer, you can fork the project add
features and send pull requests.
## Releasing CakePHP Code Sniffer
* Create a signed tag
* Write the changelog in the tag commit
+55
View File
@@ -0,0 +1,55 @@
{
"name": "cakephp/cakephp-codesniffer",
"description": "CakePHP CodeSniffer Standards",
"type": "phpcodesniffer-standard",
"keywords": ["framework", "codesniffer"],
"homepage": "https://cakephp.org",
"license": "MIT",
"authors": [
{
"name": "CakePHP Community",
"homepage": "https://github.com/cakephp/cakephp-codesniffer/graphs/contributors"
}
],
"support": {
"issues": "https://github.com/cakephp/cakephp-codesniffer/issues",
"forum": "https://stackoverflow.com/tags/cakephp",
"irc": "irc://irc.freenode.org/cakephp",
"source": "https://github.com/cakephp/cakephp-codesniffer"
},
"require": {
"php": ">=5.6",
"squizlabs/php_codesniffer": "^3.0.0"
},
"require-dev": {
"phpunit/phpunit": "<6.0"
},
"autoload": {
"psr-4": {
"CakePHP\\": "CakePHP/"
}
},
"scripts": {
"increase-severity": "sed -i.bak 's/<severity>0<\\/severity>/<!--<severity>0<\\/severity>-->/' CakePHP/ruleset.xml",
"reset-ruleset": [
"sed -i.bak 's/<!--<severity>0<\\/severity>-->/<severity>0<\\/severity>/' CakePHP/ruleset.xml",
"rm -f CakePHP/ruleset.xml.bak"
],
"add-standard" : "phpcs --config-set installed_paths $(pwd)",
"test": [
"@add-standard",
"@increase-severity",
"phpunit",
"@reset-ruleset"
],
"test-coverage": [
"@add-standard",
"@increase-severity",
"phpunit --coverage-clover=clover.xml",
"@reset-ruleset"
],
"cs-check": "vendor/bin/phpcs --colors -p -s --extensions=php CakePHP/",
"cs-fix": "vendor/bin/phpcbf --colors -p --extensions=php CakePHP/",
"explain": "vendor/bin/phpcs -e"
}
}
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<ruleset name="CakePHPSniffer">
<description>CakePHP coding standard</description>
<!-- CakePHP coding standard -->
<rule ref="CakePHP"/>
</ruleset>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<ruleset name="App">
<description>App Coding Standard</description>
<!-- CakePHP coding standard -->
<rule ref="vendor/cakephp/cakephp-codesniffer/CakePHP"/>
</ruleset>
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/squizlabs/php_codesniffer/tests/bootstrap.php">
<testsuites>
<testsuite name="CakePHP-CodeSniffer">
<file>vendor/squizlabs/php_codesniffer/tests/AllTests.php</file>
</testsuite>
</testsuites>
<!-- Prevent coverage reports from looking in tests, vendors, config folders -->
<filter>
<whitelist>
<directory suffix=".php">./CakePHP/Sniffs</directory>
</whitelist>
</filter>
</phpunit>