1<?php 2/** 3 * Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff. 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PHP_CodeSniffer 9 * @author Greg Sherwood <gsherwood@squiz.net> 10 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 11 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 12 * @link http://pear.php.net/package/PHP_CodeSniffer 13 */ 14 15/** 16 * Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff. 17 * 18 * Ensures that the value of a comparison is not assigned to a variable. 19 * 20 * @category PHP 21 * @package PHP_CodeSniffer 22 * @author Greg Sherwood <gsherwood@squiz.net> 23 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 24 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 25 * @version Release: @package_version@ 26 * @link http://pear.php.net/package/PHP_CodeSniffer 27 */ 28class Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff implements PHP_CodeSniffer_Sniff 29{ 30 31 32 /** 33 * Returns an array of tokens this test wants to listen for. 34 * 35 * @return array 36 */ 37 public function register() 38 { 39 return array(T_EQUAL); 40 41 }//end register() 42 43 44 /** 45 * Processes this test, when one of its tokens is encountered. 46 * 47 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 48 * @param int $stackPtr The position of the current token 49 * in the stack passed in $tokens. 50 * 51 * @return void 52 */ 53 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 54 { 55 $tokens = $phpcsFile->getTokens(); 56 57 // Ignore default value assignments in function definitions. 58 $function = $phpcsFile->findPrevious(T_FUNCTION, ($stackPtr - 1), null, false, null, true); 59 if ($function !== false) { 60 $opener = $tokens[$function]['parenthesis_opener']; 61 $closer = $tokens[$function]['parenthesis_closer']; 62 if ($opener < $stackPtr && $closer > $stackPtr) { 63 return; 64 } 65 } 66 67 // Ignore values in array definitions. 68 $array = $phpcsFile->findNext( 69 T_ARRAY, 70 ($stackPtr + 1), 71 null, 72 false, 73 null, 74 true 75 ); 76 77 if ($array !== false) { 78 return; 79 } 80 81 // Ignore function calls. 82 $ignore = array( 83 T_STRING, 84 T_WHITESPACE, 85 T_OBJECT_OPERATOR, 86 ); 87 88 $next = $phpcsFile->findNext($ignore, ($stackPtr + 1), null, true); 89 if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS 90 && $tokens[($next - 1)]['code'] === T_STRING 91 ) { 92 // Code will look like: $var = myFunction( 93 // and will be ignored. 94 return; 95 } 96 97 $endStatement = $phpcsFile->findNext(T_SEMICOLON, ($stackPtr + 1)); 98 if ($tokens[$stackPtr]['conditions'] !== $tokens[$endStatement]['conditions']) { 99 // This statement doesn't end with a semicolon, which is the case for 100 // the last expression in a for loop. 101 return; 102 } 103 104 for ($i = ($stackPtr + 1); $i < $endStatement; $i++) { 105 if (isset(PHP_CodeSniffer_Tokens::$comparisonTokens[$tokens[$i]['code']]) === true 106 || $tokens[$i]['code'] === T_INLINE_THEN 107 ) { 108 $error = 'The value of a comparison must not be assigned to a variable'; 109 $phpcsFile->addError($error, $stackPtr, 'AssignedComparison'); 110 break; 111 } 112 113 if (isset(PHP_CodeSniffer_Tokens::$booleanOperators[$tokens[$i]['code']]) === true 114 || $tokens[$i]['code'] === T_BOOLEAN_NOT 115 ) { 116 $error = 'The value of a boolean operation must not be assigned to a variable'; 117 $phpcsFile->addError($error, $stackPtr, 'AssignedBool'); 118 break; 119 } 120 } 121 122 }//end process() 123 124 125}//end class 126