1<?php 2/** 3 * Squiz_Sniffs_CSS_IndentationSniff. 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_CSS_IndentationSniff. 17 * 18 * Ensures styles are indented 4 spaces. 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_CSS_IndentationSniff implements PHP_CodeSniffer_Sniff 29{ 30 31 /** 32 * A list of tokenizers this sniff supports. 33 * 34 * @var array 35 */ 36 public $supportedTokenizers = array('CSS'); 37 38 /** 39 * The number of spaces code should be indented. 40 * 41 * @var int 42 */ 43 public $indent = 4; 44 45 46 /** 47 * Returns the token types that this sniff is interested in. 48 * 49 * @return int[] 50 */ 51 public function register() 52 { 53 return array(T_OPEN_TAG); 54 55 }//end register() 56 57 58 /** 59 * Processes the tokens that this sniff is interested in. 60 * 61 * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. 62 * @param int $stackPtr The position in the stack where 63 * the token was found. 64 * 65 * @return void 66 */ 67 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 68 { 69 $tokens = $phpcsFile->getTokens(); 70 71 $numTokens = (count($tokens) - 2); 72 $indentLevel = 0; 73 $nestingLevel = 0; 74 for ($i = 1; $i < $numTokens; $i++) { 75 if ($tokens[$i]['code'] === T_COMMENT) { 76 // Don't check the indent of comments. 77 continue; 78 } 79 80 if ($tokens[$i]['code'] === T_OPEN_CURLY_BRACKET) { 81 $indentLevel++; 82 83 // Check for nested class definitions. 84 $found = $phpcsFile->findNext( 85 T_OPEN_CURLY_BRACKET, 86 ($i + 1), 87 $tokens[$i]['bracket_closer'] 88 ); 89 90 if ($found !== false) { 91 $nestingLevel = $indentLevel; 92 } 93 } 94 95 if (($tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET 96 && $tokens[$i]['line'] !== $tokens[($i - 1)]['line']) 97 || ($tokens[($i + 1)]['code'] === T_CLOSE_CURLY_BRACKET 98 && $tokens[$i]['line'] === $tokens[($i + 1)]['line']) 99 ) { 100 $indentLevel--; 101 if ($indentLevel === 0) { 102 $nestingLevel = 0; 103 } 104 } 105 106 if ($tokens[$i]['column'] !== 1 107 || $tokens[$i]['code'] === T_OPEN_CURLY_BRACKET 108 || $tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET 109 ) { 110 continue; 111 } 112 113 // We started a new line, so check indent. 114 if ($tokens[$i]['code'] === T_WHITESPACE) { 115 $content = str_replace($phpcsFile->eolChar, '', $tokens[$i]['content']); 116 $foundIndent = strlen($content); 117 } else { 118 $foundIndent = 0; 119 } 120 121 $expectedIndent = ($indentLevel * $this->indent); 122 if ($expectedIndent > 0 123 && strpos($tokens[$i]['content'], $phpcsFile->eolChar) !== false 124 ) { 125 if ($nestingLevel !== $indentLevel) { 126 $error = 'Blank lines are not allowed in class definitions'; 127 $fix = $phpcsFile->addFixableError($error, $i, 'BlankLine'); 128 if ($fix === true) { 129 $phpcsFile->fixer->replaceToken($i, ''); 130 } 131 } 132 } else if ($foundIndent !== $expectedIndent) { 133 $error = 'Line indented incorrectly; expected %s spaces, found %s'; 134 $data = array( 135 $expectedIndent, 136 $foundIndent, 137 ); 138 139 $fix = $phpcsFile->addFixableError($error, $i, 'Incorrect', $data); 140 if ($fix === true) { 141 $indent = str_repeat(' ', $expectedIndent); 142 if ($foundIndent === 0) { 143 $phpcsFile->fixer->addContentBefore($i, $indent); 144 } else { 145 $phpcsFile->fixer->replaceToken($i, $indent); 146 } 147 } 148 }//end if 149 }//end for 150 151 }//end process() 152 153 154}//end class 155