1<?php 2/** 3 * Generic_Sniffs_Files_LineEndingsSniff. 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PHP_CodeSniffer 9 * @author Greg Sherwood <gsherwood@squiz.net> 10 * @author Marc McIntyre <mmcintyre@squiz.net> 11 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 12 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 13 * @link http://pear.php.net/package/PHP_CodeSniffer 14 */ 15 16/** 17 * Generic_Sniffs_Files_LineEndingsSniff. 18 * 19 * Checks that end of line characters are correct. 20 * 21 * @category PHP 22 * @package PHP_CodeSniffer 23 * @author Greg Sherwood <gsherwood@squiz.net> 24 * @author Marc McIntyre <mmcintyre@squiz.net> 25 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 26 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 27 * @version Release: @package_version@ 28 * @link http://pear.php.net/package/PHP_CodeSniffer 29 */ 30class Generic_Sniffs_Files_LineEndingsSniff implements PHP_CodeSniffer_Sniff 31{ 32 33 /** 34 * A list of tokenizers this sniff supports. 35 * 36 * @var array 37 */ 38 public $supportedTokenizers = array( 39 'PHP', 40 'JS', 41 'CSS', 42 ); 43 44 /** 45 * The valid EOL character. 46 * 47 * @var string 48 */ 49 public $eolChar = '\n'; 50 51 52 /** 53 * Returns an array of tokens this test wants to listen for. 54 * 55 * @return array 56 */ 57 public function register() 58 { 59 return array(T_OPEN_TAG); 60 61 }//end register() 62 63 64 /** 65 * Processes this sniff, when one of its tokens is encountered. 66 * 67 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 68 * @param int $stackPtr The position of the current token in 69 * the stack passed in $tokens. 70 * 71 * @return int 72 */ 73 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 74 { 75 $found = $phpcsFile->eolChar; 76 $found = str_replace("\n", '\n', $found); 77 $found = str_replace("\r", '\r', $found); 78 79 $phpcsFile->recordMetric($stackPtr, 'EOL char', $found); 80 81 if ($found === $this->eolChar) { 82 // Ignore the rest of the file. 83 return ($phpcsFile->numTokens + 1); 84 } 85 86 // Check for single line files without an EOL. This is a very special 87 // case and the EOL char is set to \n when this happens. 88 if ($found === '\n') { 89 $tokens = $phpcsFile->getTokens(); 90 $lastToken = ($phpcsFile->numTokens - 1); 91 if ($tokens[$lastToken]['line'] === 1 92 && $tokens[$lastToken]['content'] !== "\n" 93 ) { 94 return; 95 } 96 } 97 98 $error = 'End of line character is invalid; expected "%s" but found "%s"'; 99 $expected = $this->eolChar; 100 $expected = str_replace("\n", '\n', $expected); 101 $expected = str_replace("\r", '\r', $expected); 102 $data = array( 103 $expected, 104 $found, 105 ); 106 107 // Errors are always reported on line 1, no matter where the first PHP tag is. 108 $fix = $phpcsFile->addFixableError($error, 0, 'InvalidEOLChar', $data); 109 110 if ($fix === true) { 111 $tokens = $phpcsFile->getTokens(); 112 switch ($this->eolChar) { 113 case '\n': 114 $eolChar = "\n"; 115 break; 116 case '\r': 117 $eolChar = "\r"; 118 break; 119 case '\r\n': 120 $eolChar = "\r\n"; 121 break; 122 default: 123 $eolChar = $this->eolChar; 124 break; 125 } 126 127 for ($i = 0; $i < $phpcsFile->numTokens; $i++) { 128 if (isset($tokens[($i + 1)]) === false 129 || $tokens[($i + 1)]['line'] > $tokens[$i]['line'] 130 ) { 131 // Token is the last on a line. 132 if (isset($tokens[$i]['orig_content']) === true) { 133 $tokenContent = $tokens[$i]['orig_content']; 134 } else { 135 $tokenContent = $tokens[$i]['content']; 136 } 137 138 $newContent = rtrim($tokenContent, "\r\n"); 139 $newContent .= $eolChar; 140 $phpcsFile->fixer->replaceToken($i, $newContent); 141 } 142 } 143 }//end if 144 145 // Ignore the rest of the file. 146 return ($phpcsFile->numTokens + 1); 147 148 }//end process() 149 150 151}//end class 152