├── .gitignore ├── Docs └── .placeholder ├── README.md ├── Sniffs ├── Classes │ └── MultipleClassesOneFileSniff.php ├── Commenting │ ├── ClassCommentSniff.php │ └── FunctionCommentSniff.php ├── Formatting │ └── BlankLineBeforeReturnSniff.php ├── NamingConventions │ └── InterfaceSuffixSniff.php ├── Scope │ └── MethodScopeSniff.php └── WhiteSpace │ └── DiscourageFitzinatorSniff.php ├── Tests └── Formatting │ ├── BlankLineBeforeReturnUnitTest.inc │ └── BlankLineBeforeReturnUnitTest.php ├── composer.json └── ruleset.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | 3 | -------------------------------------------------------------------------------- /Docs/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leaphub/phpcs-symfony2-standard/82ba32f225cbb564b3dc65c883ee280fd03ba790/Docs/.placeholder -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Symfony2 PHP_CodeSniffer Coding Standard 2 | 3 | A composer installable coding standard to check against the [Symfony coding standards](http://symfony.com/doc/current/contributing/code/standards.html). 4 | 5 | This project was based on the [standard provided by @lapistano](https://github.com/lapistano/Symfony2-coding-standard) 6 | 7 | ## Installation 8 | 9 | This coding standard can be installed via composer or be used in you PHP_CodeSniffer install over PECL. Both ways are 10 | described in the following but the composer way is recommedend: 11 | 12 | ### Using Composer 13 | 14 | 1. Install The standard as dependency of your composer based project (It will install the composer version of PHP_CodeSniffer as dependency): 15 | 16 | $ php composer.phar require --dev leaphub/phpcs-symfony2-standard:~2.0.0 17 | 18 | 2. Profit! 19 | 20 | $ bin/phpcs --standard=vendor/leaphub/phpcs-symfony2-standard/leaphub/phpcs/Symfony2/ --extensions=php src/ 21 | 22 | ### Using PEAR 23 | 24 | 1. Install PHP_CodeSniffer: 25 | 26 | $ pear install PHP_CodeSniffer 27 | 28 | 2. Find your PEAR directory: 29 | 30 | $ pear config-show | grep php_dir 31 | 32 | 3. Copy, symlink or check out this repo to a folder called Symfony2 inside the 33 | phpcs `Standards` directory: 34 | 35 | $ cd /path/to/pear/PHP/CodeSniffer/Standards 36 | $ git clone git@github.com:leaphub/phpcs-symfony2-standard.git Symfony2 37 | 38 | 4. Set Symfony2 as your default coding standard if cou want: 39 | 40 | $ phpcs --config-set default_standard Symfony2 41 | 42 | 5. Profit! 43 | 44 | $ phpcs --standard=Symfony2 --extensions=php src/ 45 | 46 | # Contributing 47 | 48 | If you do contribute code to these sniffs, please make sure it conforms to the PEAR 49 | coding standard and that the Symfony2-coding-standard unit tests still pass. 50 | 51 | To check the coding standard, run from the Symfony2-coding-standard source root: 52 | 53 | $ phpcs --ignore=*/tests/* --standard=PEAR . -n 54 | 55 | The unit-tests are run from within the PHP_CodeSniffer directory: 56 | 57 | $ phpunit --filter Symfony2_* tests/AllTests.php 58 | -------------------------------------------------------------------------------- /Sniffs/Classes/MultipleClassesOneFileSniff.php: -------------------------------------------------------------------------------- 1 | 11 | * @license http://spdx.org/licenses/MIT MIT License 12 | * @version GIT: master 13 | * @link https://github.com/opensky/Symfony2-coding-standard 14 | */ 15 | 16 | /** 17 | * Symfony2_Sniffs_Classes_MultipleClassesOneFileSniff. 18 | * 19 | * Throws errors if multiple classes are defined in a single file. 20 | * 21 | * Symfony coding standard specifies: "Define one class per file;" 22 | * 23 | * @category PHP 24 | * @package PHP_CodeSniffer-Symfony2 25 | * @author Dave Hauenstein 26 | * @license http://spdx.org/licenses/MIT MIT License 27 | * @link https://github.com/opensky/Symfony2-coding-standard 28 | */ 29 | class Symfony2_Sniffs_Classes_MultipleClassesOneFileSniff implements PHP_CodeSniffer_Sniff 30 | { 31 | /** 32 | * The number of times the T_CLASS token is encountered in the file. 33 | * 34 | * @var int 35 | */ 36 | protected $classCount = 0; 37 | 38 | /** 39 | * The current file this class is operating on. 40 | * 41 | * @var string 42 | */ 43 | protected $currentFile; 44 | 45 | /** 46 | * A list of tokenizers this sniff supports. 47 | * 48 | * @var array 49 | */ 50 | public $supportedTokenizers = array( 51 | 'PHP', 52 | ); 53 | 54 | /** 55 | * Returns an array of tokens this test wants to listen for. 56 | * 57 | * @return array 58 | */ 59 | public function register() 60 | { 61 | return array(T_CLASS); 62 | } 63 | 64 | /** 65 | * Processes this test, when one of its tokens is encountered. 66 | * 67 | * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. 68 | * @param int $stackPtr The position of the current token in 69 | * the stack passed in $tokens. 70 | * 71 | * @return void 72 | */ 73 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 74 | { 75 | if ($this->currentFile !== $phpcsFile->getFilename()) { 76 | $this->classCount = 0; 77 | $this->currentFile = $phpcsFile->getFilename(); 78 | } 79 | 80 | $this->classCount++; 81 | 82 | if ($this->classCount > 1) { 83 | $phpcsFile->addError( 84 | 'Multiple classes defined in a single file', 85 | $stackPtr 86 | ); 87 | } 88 | 89 | return; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Sniffs/Commenting/ClassCommentSniff.php: -------------------------------------------------------------------------------- 1 | 10 | * @author Marc McIntyre 11 | * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) 12 | * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence 13 | * @version CVS: $Id: ClassCommentSniff.php 301632 2010-07-28 01:57:56Z squiz $ 14 | * @link http://pear.php.net/package/PHP_CodeSniffer 15 | */ 16 | 17 | if (class_exists('PHP_CodeSniffer_Tokenizers_Comment', true) === false) { 18 | $error = 'Class PHP_CodeSniffer_Tokenizers_Comment not found'; 19 | throw new PHP_CodeSniffer_Exception($error); 20 | } 21 | 22 | if (class_exists('PEAR_Sniffs_Commenting_ClassCommentSniff', true) === false) { 23 | $error = 'Class PEAR_Sniffs_Commenting_ClassCommentSniff not found'; 24 | throw new PHP_CodeSniffer_Exception($error); 25 | } 26 | 27 | /** 28 | * Parses and verifies the doc comments for classes. 29 | * 30 | * Verifies that : 31 | * 40 | * 41 | * @category PHP 42 | * @package PHP_CodeSniffer 43 | * @author Greg Sherwood 44 | * @author Marc McIntyre 45 | * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) 46 | * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence 47 | * @version Release: 1.3.0RC2 48 | * @link http://pear.php.net/package/PHP_CodeSniffer 49 | */ 50 | class Symfony2_Sniffs_Commenting_ClassCommentSniff extends PEAR_Sniffs_Commenting_ClassCommentSniff 51 | { 52 | /** 53 | * Tags in correct order and related info. 54 | * 55 | * @var array 56 | */ 57 | protected $tags = array( 58 | 'category' => array( 59 | 'required' => false, 60 | 'allow_multiple' => false, 61 | 'order_text' => 'precedes @package', 62 | ), 63 | 'package' => array( 64 | 'required' => false, 65 | 'allow_multiple' => false, 66 | 'order_text' => 'follows @category', 67 | ), 68 | 'subpackage' => array( 69 | 'required' => false, 70 | 'allow_multiple' => false, 71 | 'order_text' => 'follows @package', 72 | ), 73 | 'author' => array( 74 | 'required' => false, 75 | 'allow_multiple' => true, 76 | 'order_text' => 'follows @subpackage (if used) or @package', 77 | ), 78 | 'copyright' => array( 79 | 'required' => false, 80 | 'allow_multiple' => true, 81 | 'order_text' => 'follows @author', 82 | ), 83 | 'license' => array( 84 | 'required' => false, 85 | 'allow_multiple' => false, 86 | 'order_text' => 'follows @copyright (if used) or @author', 87 | ), 88 | 'version' => array( 89 | 'required' => false, 90 | 'allow_multiple' => false, 91 | 'order_text' => 'follows @license', 92 | ), 93 | 'link' => array( 94 | 'required' => false, 95 | 'allow_multiple' => true, 96 | 'order_text' => 'follows @version', 97 | ), 98 | 'see' => array( 99 | 'required' => false, 100 | 'allow_multiple' => true, 101 | 'order_text' => 'follows @link', 102 | ), 103 | 'since' => array( 104 | 'required' => false, 105 | 'allow_multiple' => false, 106 | 'order_text' => 'follows @see (if used) or @link', 107 | ), 108 | 'deprecated' => array( 109 | 'required' => false, 110 | 'allow_multiple' => false, 111 | 'order_text' => 'follows @since (if used) or @see (if used) or @link', 112 | ), 113 | ); 114 | } 115 | -------------------------------------------------------------------------------- /Sniffs/Commenting/FunctionCommentSniff.php: -------------------------------------------------------------------------------- 1 | 10 | * @license http://spdx.org/licenses/MIT MIT License 11 | * @version GIT: master 12 | * @link https://github.com/opensky/Symfony2-coding-standard 13 | */ 14 | 15 | if (class_exists('PEAR_Sniffs_Commenting_FunctionCommentSniff', true) === false) { 16 | $error = 'Class PEAR_Sniffs_Commenting_FunctionCommentSniff not found'; 17 | throw new PHP_CodeSniffer_Exception($error); 18 | } 19 | 20 | /** 21 | * Symfony2 standard customization to PEARs FunctionCommentSniff. 22 | * 23 | * Verifies that : 24 | *
    25 | *
  • There is a @return tag if a return statement exists inside the method
  • 26 | *
27 | * 28 | * @category PHP 29 | * @package PHP_CodeSniffer 30 | * @author Felix Brandt 31 | * @license http://spdx.org/licenses/BSD-3-Clause BSD 3-clause "New" or "Revised" License 32 | * @link http://pear.php.net/package/PHP_CodeSniffer 33 | */ 34 | class Symfony2_Sniffs_Commenting_FunctionCommentSniff extends PEAR_Sniffs_Commenting_FunctionCommentSniff 35 | { 36 | 37 | /** 38 | * @var string 39 | */ 40 | public $requiredScopes = 'public'; 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 46 | { 47 | if (false === $commentEnd = $phpcsFile->findPrevious(array(T_COMMENT, T_DOC_COMMENT, T_CLASS, T_FUNCTION, T_OPEN_TAG), ($stackPtr - 1))) { 48 | return; 49 | } 50 | 51 | $tokens = $phpcsFile->getTokens(); 52 | $code = $tokens[$commentEnd]['code']; 53 | 54 | // a comment is not required on protected/private methods 55 | $method = $phpcsFile->getMethodProperties($stackPtr); 56 | $commentRequired = $this->isRequiredScope($method['scope']); 57 | 58 | if (($code === T_COMMENT && !$commentRequired) 59 | || ($code !== T_DOC_COMMENT && !$commentRequired) 60 | ) { 61 | return; 62 | } 63 | 64 | parent::process($phpcsFile, $stackPtr); 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | protected function processReturn(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $commentStart) 71 | { 72 | if ($this->isInheritDoc($phpcsFile, $stackPtr)) { 73 | return; 74 | } 75 | 76 | $tokens = $phpcsFile->getTokens(); 77 | $funcPtr = $phpcsFile->findNext(T_FUNCTION, $commentStart); 78 | 79 | // Only check for a return comment if a non-void return statement exists 80 | if (isset($tokens[$stackPtr]['scope_opener'])) { 81 | $start = $tokens[$stackPtr]['scope_opener']; 82 | 83 | // iterate over all return statements of this function, 84 | // run the check on the first which is not only 'return;' 85 | while ($returnToken = $phpcsFile->findNext(T_RETURN, $start, $tokens[$stackPtr]['scope_closer'])) { 86 | if ($this->isMatchingReturn($tokens, $returnToken)) { 87 | parent::processReturn($phpcsFile, $stackPtr, $commentStart); 88 | break; 89 | } 90 | $start = $returnToken + 1; 91 | } 92 | } 93 | 94 | } /* end processReturn() */ 95 | 96 | /** 97 | * Checks if the comment an inheritdoc? 98 | * 99 | * @param PHP_CodeSniffer_File $phpcsFile 100 | * @param int $stackPtr 101 | * 102 | * @return bool 103 | */ 104 | protected function isInheritDoc(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 105 | { 106 | $tokens = $phpcsFile->getTokens(); 107 | $start = $phpcsFile->findPrevious(T_DOC_COMMENT_OPEN_TAG, $stackPtr - 1); 108 | $end = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $start); 109 | 110 | $content = $phpcsFile->getTokensAsString($start, ($end - $start)); 111 | 112 | return preg_match('#{@inheritdoc}#i', $content) === 1; 113 | } // end isInheritDoc() 114 | 115 | /** 116 | * {@inheritdoc} 117 | */ 118 | protected function processParams(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $commentStart) 119 | { 120 | if ($this->isInheritDoc($phpcsFile, $stackPtr)) { 121 | return; 122 | } 123 | 124 | parent::processParams($phpcsFile, $stackPtr, $commentStart); 125 | } // end processParams() 126 | 127 | /** 128 | * Is the return statement matching? 129 | * 130 | * @param array $tokens Array of tokens 131 | * @param int $returnPos Stack position of the T_RETURN token to process 132 | * 133 | * @return boolean True if the return does not return anything 134 | */ 135 | protected function isMatchingReturn($tokens, $returnPos) 136 | { 137 | do { 138 | $returnPos++; 139 | } while ($tokens[$returnPos]['code'] === T_WHITESPACE); 140 | 141 | return $tokens[$returnPos]['code'] !== T_SEMICOLON; 142 | } 143 | 144 | /** 145 | * Check if the given function visibility scope needs to have a docblock. 146 | * 147 | * @param string $scope Visibility scope of the function. 148 | * 149 | * @return bool 150 | */ 151 | protected function isRequiredScope($scope) 152 | { 153 | return strpos($this->requiredScopes, $scope) !== FALSE; 154 | } 155 | 156 | }//end class 157 | -------------------------------------------------------------------------------- /Sniffs/Formatting/BlankLineBeforeReturnSniff.php: -------------------------------------------------------------------------------- 1 | 11 | * @license http://spdx.org/licenses/MIT MIT License 12 | * @version GIT: master 13 | * @link https://github.com/opensky/Symfony2-coding-standard 14 | */ 15 | 16 | /** 17 | * Symfony2_Sniffs_Formatting_BlankLineBeforeReturnSniff. 18 | * 19 | * Throws errors if there's no blank line before return statements. Symfony 20 | * coding standard specifies: "Add a blank line before return statements, 21 | * unless the return is alone inside a statement-group (like an if statement);" 22 | * 23 | * @category PHP 24 | * @package PHP_CodeSniffer-Symfony2 25 | * @author Dave Hauenstein 26 | * @license http://spdx.org/licenses/MIT MIT License 27 | * @link https://github.com/opensky/Symfony2-coding-standard 28 | */ 29 | class Symfony2_Sniffs_Formatting_BlankLineBeforeReturnSniff implements PHP_CodeSniffer_Sniff 30 | { 31 | /** 32 | * A list of tokenizers this sniff supports. 33 | * 34 | * @var array 35 | */ 36 | public $supportedTokenizers = array( 37 | 'PHP', 38 | 'JS', 39 | ); 40 | 41 | /** 42 | * Returns an array of tokens this test wants to listen for. 43 | * 44 | * @return array 45 | */ 46 | public function register() 47 | { 48 | return array(T_RETURN); 49 | } 50 | 51 | /** 52 | * Processes this test, when one of its tokens is encountered. 53 | * 54 | * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. 55 | * @param int $stackPtr The position of the current token in 56 | * the stack passed in $tokens. 57 | * 58 | * @return void 59 | */ 60 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 61 | { 62 | $tokens = $phpcsFile->getTokens(); 63 | $current = $stackPtr; 64 | $previousLine = $tokens[$stackPtr]['line'] - 1; 65 | $prevLineTokens = array(); 66 | 67 | while ($current >= 0 && $tokens[$current]['line'] >= $previousLine) { 68 | if ($tokens[$current]['line'] == $previousLine 69 | && $tokens[$current]['type'] !== 'T_WHITESPACE' 70 | && $tokens[$current]['type'] !== 'T_COMMENT' 71 | ) { 72 | $prevLineTokens[] = $tokens[$current]['type']; 73 | } 74 | $current--; 75 | } 76 | 77 | if (isset($prevLineTokens[0]) 78 | && ($prevLineTokens[0] === 'T_OPEN_CURLY_BRACKET' 79 | || $prevLineTokens[0] === 'T_COLON') 80 | ) { 81 | return; 82 | } else if (count($prevLineTokens) > 0) { 83 | $phpcsFile->addError( 84 | 'Missing blank line before return statement', 85 | $stackPtr 86 | ); 87 | } 88 | 89 | return; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Sniffs/NamingConventions/InterfaceSuffixSniff.php: -------------------------------------------------------------------------------- 1 | 10 | * @license http://spdx.org/licenses/MIT MIT License 11 | * @version GIT: master 12 | * @link https://github.com/opensky/Symfony2-coding-standard 13 | */ 14 | 15 | /** 16 | * Symfony2_Sniffs_NamingConventions_InterfaceSuffixSniff. 17 | * 18 | * Throws errors if interface names are not suffixed with "Interface". 19 | * 20 | * Symfony coding standard specifies: "Suffix interfaces with Interface;" 21 | * 22 | * @category PHP 23 | * @package PHP_CodeSniffer-Symfony2 24 | * @author Dave Hauenstein 25 | * @license http://spdx.org/licenses/MIT MIT License 26 | * @link https://github.com/opensky/Symfony2-coding-standard 27 | */ 28 | class Symfony2_Sniffs_NamingConventions_InterfaceSuffixSniff implements PHP_CodeSniffer_Sniff 29 | { 30 | /** 31 | * A list of tokenizers this sniff supports. 32 | * 33 | * @var array 34 | */ 35 | public $supportedTokenizers = array( 36 | 'PHP', 37 | ); 38 | 39 | /** 40 | * Returns an array of tokens this test wants to listen for. 41 | * 42 | * @return array 43 | */ 44 | public function register() 45 | { 46 | return array(T_INTERFACE); 47 | } 48 | 49 | /** 50 | * Processes this test, when one of its tokens is encountered. 51 | * 52 | * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. 53 | * @param int $stackPtr The position of the current token in 54 | * the stack passed in $tokens. 55 | * 56 | * @return void 57 | */ 58 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 59 | { 60 | $tokens = $phpcsFile->getTokens(); 61 | $line = $tokens[$stackPtr]['line']; 62 | 63 | while ($tokens[$stackPtr]['line'] == $line) { 64 | if ('T_STRING' == $tokens[$stackPtr]['type']) { 65 | if (substr($tokens[$stackPtr]['content'], -9) != 'Interface') { 66 | $phpcsFile->addError( 67 | 'Interface name is not suffixed with "Interface"', 68 | $stackPtr 69 | ); 70 | } 71 | break; 72 | } 73 | $stackPtr++; 74 | } 75 | 76 | return; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Sniffs/Scope/MethodScopeSniff.php: -------------------------------------------------------------------------------- 1 | 10 | * @author Marc McIntyre 11 | * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) 12 | * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence 13 | * @version CVS: $Id: MethodScopeSniff.php 301632 2010-07-28 01:57:56Z squiz $ 14 | * @link http://pear.php.net/package/PHP_CodeSniffer 15 | */ 16 | 17 | if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) { 18 | throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found'); 19 | } 20 | 21 | /** 22 | * Verifies that class members have scope modifiers. 23 | * 24 | * @category PHP 25 | * @package PHP_CodeSniffer 26 | * @author Greg Sherwood 27 | * @author Marc McIntyre 28 | * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) 29 | * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence 30 | * @version Release: 1.3.0 31 | * @link http://pear.php.net/package/PHP_CodeSniffer 32 | */ 33 | class Symfony2_Sniffs_Scope_MethodScopeSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff 34 | { 35 | /** 36 | * Constructs a Symfony2_Sniffs_Scope_MethodScopeSniff. 37 | */ 38 | public function __construct() 39 | { 40 | parent::__construct(array(T_CLASS), array(T_FUNCTION)); 41 | 42 | }//end __construct() 43 | 44 | /** 45 | * Processes the function tokens within the class. 46 | * 47 | * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. 48 | * @param int $stackPtr The position where the token was found. 49 | * @param int $currScope The current scope opener token. 50 | * 51 | * @return void 52 | */ 53 | protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) 54 | { 55 | $tokens = $phpcsFile->getTokens(); 56 | 57 | $methodName = $phpcsFile->getDeclarationName($stackPtr); 58 | if ($methodName === null) { 59 | // Ignore closures. 60 | return; 61 | } 62 | 63 | $modifier = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$scopeModifiers, $stackPtr); 64 | if (($modifier === false) || ($tokens[$modifier]['line'] !== $tokens[$stackPtr]['line'])) { 65 | $error = 'No scope modifier specified for function "%s"'; 66 | $data = array($methodName); 67 | $phpcsFile->addError($error, $stackPtr, 'Missing', $data); 68 | } 69 | 70 | }//end processTokenWithinScope() 71 | }//end class 72 | -------------------------------------------------------------------------------- /Sniffs/WhiteSpace/DiscourageFitzinatorSniff.php: -------------------------------------------------------------------------------- 1 | 10 | * @license http://spdx.org/licenses/MIT MIT License 11 | * @version GIT: master 12 | * @link https://github.com/opensky/Symfony2-coding-standard 13 | */ 14 | 15 | /** 16 | * Symfony2_Sniffs_WhiteSpace_DiscourageFitzinatorSniff. 17 | * 18 | * Throws warnings if a file contains trailing whitespace. 19 | * 20 | * @category PHP 21 | * @package PHP_CodeSniffer-Symfony2 22 | * @author Justin Hileman 23 | * @license http://spdx.org/licenses/MIT MIT License 24 | * @link https://github.com/opensky/Symfony2-coding-standard 25 | */ 26 | class Symfony2_Sniffs_WhiteSpace_DiscourageFitzinatorSniff implements PHP_CodeSniffer_Sniff 27 | { 28 | 29 | /** 30 | * A list of tokenizers this sniff supports. 31 | * 32 | * @var array 33 | */ 34 | public $supportedTokenizers = array( 35 | 'PHP', 36 | 'JS', 37 | 'CSS', 38 | ); 39 | 40 | 41 | /** 42 | * Returns an array of tokens this test wants to listen for. 43 | * 44 | * @return array 45 | */ 46 | public function register() 47 | { 48 | return array(T_WHITESPACE); 49 | 50 | } 51 | 52 | 53 | /** 54 | * Processes this test, when one of its tokens is encountered. 55 | * 56 | * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document. 57 | * @param int $stackPtr The position of the current token in 58 | * the stack passed in $tokens. 59 | * 60 | * @return void 61 | */ 62 | public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 63 | { 64 | $tokens = $phpcsFile->getTokens(); 65 | 66 | // Make sure this is trailing whitespace. 67 | $line = $tokens[$stackPtr]['line']; 68 | if (($stackPtr < count($tokens) - 1) && $tokens[($stackPtr + 1)]['line'] === $line) { 69 | return; 70 | } 71 | 72 | if (strpos($tokens[$stackPtr]['content'], "\n") > 0 || strpos($tokens[$stackPtr]['content'], "\r") > 0) { 73 | $warning = 'Please trim any trailing whitespace'; 74 | $phpcsFile->addWarning($warning, $stackPtr); 75 | } 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /Tests/Formatting/BlankLineBeforeReturnUnitTest.inc: -------------------------------------------------------------------------------- 1 | 10 | * @license http://spdx.org/licenses/MIT MIT License 11 | * @version GIT: master 12 | * @link https://github.com/opensky/Symfony2-coding-standard 13 | */ 14 | 15 | /** 16 | * Unit test class for the BlankLineBeforeReturn sniff. 17 | * 18 | * A sniff unit test checks a .inc file for expected violations of a single 19 | * coding standard. Expected errors and warnings are stored in this class. 20 | * 21 | * @category PHP 22 | * @package PHP_CodeSniffer 23 | * @author Tom Klingenberg 24 | * @copyright 2012 Tom Klingenberg, some rights reserved. 25 | * @license http://spdx.org/licenses/MIT MIT License 26 | * @link https://github.com/opensky/Symfony2-coding-standard 27 | */ 28 | class Symfony2_Tests_Formatting_BlankLineBeforeReturnUnitTest extends AbstractSniffUnitTest 29 | { 30 | /** 31 | * Returns the lines where errors should occur. 32 | * 33 | * The key of the array should represent the line number and the value 34 | * should represent the number of errors that should occur on that line. 35 | * 36 | * @return array(int => int) 37 | */ 38 | public function getErrorList() 39 | { 40 | return array( 41 | 23 => 1, 42 | ); 43 | 44 | } 45 | 46 | /** 47 | * Returns the lines where warnings should occur. 48 | * 49 | * The key of the array should represent the line number and the value 50 | * should represent the number of warnings that should occur on that line. 51 | * 52 | * @return array(int => int) 53 | */ 54 | public function getWarningList() 55 | { 56 | return array(); 57 | 58 | } 59 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaphub/phpcs-symfony2-standard", 3 | "keywords": ["phpcs", "Symfony 2", "coding standard"], 4 | "homepage": "https://github.com/leaphub/phpcs-symfony2-standard", 5 | "description": "A PHP_CodeSniffer standard for Symfony 2 applications", 6 | "license": "MIT", 7 | "require": { 8 | "squizlabs/php_codesniffer": "~2.0" 9 | }, 10 | "target-dir": "leaphub/phpcs/Symfony2", 11 | "extra": { 12 | "branch-alias": { 13 | "dev-master": "2.1-dev" 14 | } 15 | }, 16 | "abandoned": "slevomat/coding-standard" 17 | } 18 | -------------------------------------------------------------------------------- /ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | The Symfony2 coding standard. 4 | 5 | 6 | */Resources/* 7 | 8 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 0 70 | 71 | 72 | 73 | 74 | 0 75 | 76 | 77 | 78 | 79 | 0 80 | 81 | 82 | 0 83 | 84 | 85 | 0 86 | 87 | 88 | 89 | 90 | 0 91 | 92 | 93 | 94 | 0 95 | 96 | 97 | 98 | There should always be a description, followed by a blank line, before the tags of a class comment. 99 | 100 | 101 | 102 | 103 | --------------------------------------------------------------------------------