1<?php 2/** 3 * Squiz_Sniffs_Strings_ConcatenationSpacingSniff. 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 * Squiz_Sniffs_Strings_ConcatenationSpacingSniff. 18 * 19 * Makes sure there are no spaces between the concatenation operator (.) and 20 * the strings being concatenated. 21 * 22 * @category PHP 23 * @package PHP_CodeSniffer 24 * @author Greg Sherwood <gsherwood@squiz.net> 25 * @author Marc McIntyre <mmcintyre@squiz.net> 26 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 27 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 28 * @version Release: @package_version@ 29 * @link http://pear.php.net/package/PHP_CodeSniffer 30 */ 31class Squiz_Sniffs_Strings_ConcatenationSpacingSniff implements PHP_CodeSniffer_Sniff 32{ 33 34 /** 35 * The number of spaces before and after a string concat. 36 * 37 * @var int 38 */ 39 public $spacing = 0; 40 41 /** 42 * Allow newlines instead of spaces. 43 * 44 * @var boolean 45 */ 46 public $ignoreNewlines = false; 47 48 49 /** 50 * Returns an array of tokens this test wants to listen for. 51 * 52 * @return array 53 */ 54 public function register() 55 { 56 return array(T_STRING_CONCAT); 57 58 }//end register() 59 60 61 /** 62 * Processes this test, when one of its tokens is encountered. 63 * 64 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 65 * @param int $stackPtr The position of the current token in the 66 * stack passed in $tokens. 67 * 68 * @return void 69 */ 70 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 71 { 72 $this->spacing = (int) $this->spacing; 73 74 $tokens = $phpcsFile->getTokens(); 75 if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) { 76 $before = 0; 77 } else { 78 if ($tokens[($stackPtr - 2)]['line'] !== $tokens[$stackPtr]['line']) { 79 $before = 'newline'; 80 } else { 81 $before = $tokens[($stackPtr - 1)]['length']; 82 } 83 } 84 85 if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) { 86 $after = 0; 87 } else { 88 if ($tokens[($stackPtr + 2)]['line'] !== $tokens[$stackPtr]['line']) { 89 $after = 'newline'; 90 } else { 91 $after = $tokens[($stackPtr + 1)]['length']; 92 } 93 } 94 95 $phpcsFile->recordMetric($stackPtr, 'Spacing before string concat', $before); 96 $phpcsFile->recordMetric($stackPtr, 'Spacing after string concat', $after); 97 98 if (($before === $this->spacing || ($before === 'newline' && $this->ignoreNewlines === true)) 99 && ($after === $this->spacing || ($after === 'newline' && $this->ignoreNewlines === true)) 100 ) { 101 return; 102 } 103 104 if ($this->spacing === 0) { 105 $message = 'Concat operator must not be surrounded by spaces'; 106 $data = array(); 107 } else { 108 if ($this->spacing > 1) { 109 $message = 'Concat operator must be surrounded by %s spaces'; 110 } else { 111 $message = 'Concat operator must be surrounded by a single space'; 112 } 113 114 $data = array($this->spacing); 115 } 116 117 $fix = $phpcsFile->addFixableError($message, $stackPtr, 'PaddingFound', $data); 118 119 if ($fix === true) { 120 $padding = str_repeat(' ', $this->spacing); 121 if ($before !== 'newline' || $this->ignoreNewlines === false) { 122 if ($tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { 123 $phpcsFile->fixer->beginChangeset(); 124 $phpcsFile->fixer->replaceToken(($stackPtr - 1), $padding); 125 if ($this->spacing === 0 126 && ($tokens[($stackPtr - 2)]['code'] === T_LNUMBER 127 || $tokens[($stackPtr - 2)]['code'] === T_DNUMBER) 128 ) { 129 $phpcsFile->fixer->replaceToken(($stackPtr - 2), '('.$tokens[($stackPtr - 2)]['content'].')'); 130 } 131 132 $phpcsFile->fixer->endChangeset(); 133 } else if ($this->spacing > 0) { 134 $phpcsFile->fixer->addContent(($stackPtr - 1), $padding); 135 } 136 } 137 138 if ($after !== 'newline' || $this->ignoreNewlines === false) { 139 if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) { 140 $phpcsFile->fixer->beginChangeset(); 141 $phpcsFile->fixer->replaceToken(($stackPtr + 1), $padding); 142 if ($this->spacing === 0 143 && ($tokens[($stackPtr + 2)]['code'] === T_LNUMBER 144 || $tokens[($stackPtr + 2)]['code'] === T_DNUMBER) 145 ) { 146 $phpcsFile->fixer->replaceToken(($stackPtr + 2), '('.$tokens[($stackPtr + 2)]['content'].')'); 147 } 148 149 $phpcsFile->fixer->endChangeset(); 150 } else if ($this->spacing > 0) { 151 $phpcsFile->fixer->addContent($stackPtr, $padding); 152 } 153 } 154 }//end if 155 156 }//end process() 157 158 159}//end class 160