| Conditions | 41 |
| Paths | 3633 |
| Total Lines | 233 |
| Code Lines | 110 |
| Lines | 4 |
| Ratio | 1.72 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 120 | public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) { |
||
| 121 | // Merge any custom functions with the defaults, if we haven't already. |
||
| 122 | if ( ! self::$addedCustomFunctions ) { |
||
| 123 | self::$escapingFunctions = array_merge( self::$escapingFunctions, array_flip( $this->customEscapingFunctions ) ); |
||
| 124 | self::$autoEscapedFunctions = array_merge( self::$autoEscapedFunctions, array_flip( $this->customAutoEscapedFunctions ) ); |
||
| 125 | self::$printingFunctions = array_merge( self::$printingFunctions, array_flip( $this->customPrintingFunctions ) ); |
||
| 126 | |||
| 127 | if ( ! empty( $this->customSanitizingFunctions ) ) { |
||
| 128 | self::$escapingFunctions = array_merge( self::$escapingFunctions, array_flip( $this->customSanitizingFunctions ) ); |
||
| 129 | $phpcsFile->addWarning( 'The customSanitizingFunctions property is deprecated in favor of customEscapingFunctions.', 0, 'DeprecatedCustomSanitizingFunctions' ); |
||
| 130 | } |
||
| 131 | |||
| 132 | self::$addedCustomFunctions = true; |
||
| 133 | } |
||
| 134 | |||
| 135 | $this->init( $phpcsFile ); |
||
| 136 | |||
| 137 | $function = $this->tokens[ $stackPtr ]['content']; |
||
| 138 | |||
| 139 | // Find the opening parenthesis (if present; T_ECHO might not have it). |
||
| 140 | $open_paren = $phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true ); |
||
| 141 | |||
| 142 | // If function, not T_ECHO nor T_PRINT. |
||
| 143 | if ( T_STRING === $this->tokens[ $stackPtr ]['code'] ) { |
||
| 144 | // Skip if it is a function but is not of the printing functions. |
||
| 145 | if ( ! isset( self::$printingFunctions[ $this->tokens[ $stackPtr ]['content'] ] ) ) { |
||
| 146 | return; |
||
| 147 | } |
||
| 148 | |||
| 149 | if ( isset( $this->tokens[ $open_paren ]['parenthesis_closer'] ) ) { |
||
| 150 | $end_of_statement = $this->tokens[ $open_paren ]['parenthesis_closer']; |
||
| 151 | } |
||
| 152 | |||
| 153 | // These functions only need to have the first argument escaped. |
||
| 154 | if ( in_array( $function, array( 'trigger_error', 'user_error' ), true ) ) { |
||
| 155 | $end_of_statement = $phpcsFile->findEndOfStatement( $open_paren + 1 ); |
||
| 156 | } |
||
| 157 | } |
||
| 158 | |||
| 159 | // Checking for the ignore comment, ex: //xss ok. |
||
| 160 | if ( $this->has_whitelist_comment( 'xss', $stackPtr ) ) { |
||
| 161 | return; |
||
| 162 | } |
||
| 163 | |||
| 164 | if ( isset( $end_of_statement, self::$unsafePrintingFunctions[ $function ] ) ) { |
||
| 165 | $error = $phpcsFile->addError( "Expected next thing to be an escaping function (like %s), not '%s'", $stackPtr, 'UnsafePrintingFunction', array( self::$unsafePrintingFunctions[ $function ], $function ) ); |
||
| 166 | |||
| 167 | // If the error was reported, don't bother checking the function's arguments. |
||
| 168 | if ( $error ) { |
||
| 169 | return $end_of_statement; |
||
| 170 | } |
||
| 171 | } |
||
| 172 | |||
| 173 | $ternary = false; |
||
| 174 | |||
| 175 | // This is already determined if this is a function and not T_ECHO. |
||
| 176 | if ( ! isset( $end_of_statement ) ) { |
||
| 177 | |||
| 178 | $end_of_statement = $phpcsFile->findNext( array( T_SEMICOLON, T_CLOSE_TAG ), $stackPtr ); |
||
| 179 | $last_token = $phpcsFile->findPrevious( PHP_CodeSniffer_Tokens::$emptyTokens, ( $end_of_statement - 1 ), null, true ); |
||
| 180 | |||
| 181 | // Check for the ternary operator. We only need to do this here if this |
||
| 182 | // echo is lacking parenthesis. Otherwise it will be handled below. |
||
| 183 | if ( T_OPEN_PARENTHESIS !== $this->tokens[ $open_paren ]['code'] || T_CLOSE_PARENTHESIS !== $this->tokens[ $last_token ]['code'] ) { |
||
| 184 | |||
| 185 | $ternary = $phpcsFile->findNext( T_INLINE_THEN, $stackPtr, $end_of_statement ); |
||
| 186 | |||
| 187 | // If there is a ternary skip over the part before the ?. However, if |
||
| 188 | // the ternary is within parentheses, it will be handled in the loop. |
||
| 189 | if ( $ternary && empty( $this->tokens[ $ternary ]['nested_parenthesis'] ) ) { |
||
| 190 | $stackPtr = $ternary; |
||
| 191 | } |
||
| 192 | } |
||
| 193 | } |
||
| 194 | |||
| 195 | // Ignore the function itself. |
||
| 196 | $stackPtr++; |
||
| 197 | |||
| 198 | $in_cast = false; |
||
| 199 | |||
| 200 | // Looping through echo'd components. |
||
| 201 | $watch = true; |
||
| 202 | for ( $i = $stackPtr; $i < $end_of_statement; $i++ ) { |
||
| 203 | |||
| 204 | // Ignore whitespaces and comments. |
||
| 205 | if ( in_array( $this->tokens[ $i ]['code'], PHP_CodeSniffer_Tokens::$emptyTokens, true ) ) { |
||
| 206 | continue; |
||
| 207 | } |
||
| 208 | |||
| 209 | if ( T_OPEN_PARENTHESIS === $this->tokens[ $i ]['code'] ) { |
||
| 210 | |||
| 211 | if ( $in_cast ) { |
||
| 212 | |||
| 213 | // Skip to the end of a function call if it has been casted to a safe value. |
||
| 214 | $i = $this->tokens[ $i ]['parenthesis_closer']; |
||
| 215 | $in_cast = false; |
||
| 216 | |||
| 217 | } else { |
||
| 218 | |||
| 219 | // Skip over the condition part of a ternary (i.e., to after the ?). |
||
| 220 | $ternary = $phpcsFile->findNext( T_INLINE_THEN, $i, $this->tokens[ $i ]['parenthesis_closer'] ); |
||
| 221 | |||
| 222 | if ( $ternary ) { |
||
| 223 | |||
| 224 | $next_paren = $phpcsFile->findNext( T_OPEN_PARENTHESIS, ( $i + 1 ), $this->tokens[ $i ]['parenthesis_closer'] ); |
||
| 225 | |||
| 226 | // We only do it if the ternary isn't within a subset of parentheses. |
||
| 227 | if ( ! $next_paren || $ternary > $this->tokens[ $next_paren ]['parenthesis_closer'] ) { |
||
| 228 | $i = $ternary; |
||
| 229 | } |
||
| 230 | } |
||
| 231 | } |
||
| 232 | |||
| 233 | continue; |
||
| 234 | } |
||
| 235 | |||
| 236 | // Handle arrays for those functions that accept them. |
||
| 237 | if ( T_ARRAY === $this->tokens[ $i ]['code'] ) { |
||
| 238 | $i++; // Skip the opening parenthesis. |
||
| 239 | continue; |
||
| 240 | } |
||
| 241 | |||
| 242 | if ( in_array( $this->tokens[ $i ]['code'], array( T_DOUBLE_ARROW, T_CLOSE_PARENTHESIS ), true ) ) { |
||
| 243 | continue; |
||
| 244 | } |
||
| 245 | |||
| 246 | // Handle magic constants for debug functions. |
||
| 247 | if ( isset( $this->magic_constant_tokens[ $this->tokens[ $i ]['type'] ] ) ) { |
||
| 248 | continue; |
||
| 249 | } |
||
| 250 | |||
| 251 | // Wake up on concatenation characters, another part to check. |
||
| 252 | if ( in_array( $this->tokens[ $i ]['code'], array( T_STRING_CONCAT ), true ) ) { |
||
| 253 | $watch = true; |
||
| 254 | continue; |
||
| 255 | } |
||
| 256 | |||
| 257 | // Wake up after a ternary else (:). |
||
| 258 | if ( $ternary && in_array( $this->tokens[ $i ]['code'], array( T_INLINE_ELSE ), true ) ) { |
||
| 259 | $watch = true; |
||
| 260 | continue; |
||
| 261 | } |
||
| 262 | |||
| 263 | // Wake up for commas. |
||
| 264 | if ( T_COMMA === $this->tokens[ $i ]['code'] ) { |
||
| 265 | $in_cast = false; |
||
| 266 | $watch = true; |
||
| 267 | continue; |
||
| 268 | } |
||
| 269 | |||
| 270 | if ( false === $watch ) { |
||
| 271 | continue; |
||
| 272 | } |
||
| 273 | |||
| 274 | // Allow T_CONSTANT_ENCAPSED_STRING eg: echo 'Some String'; |
||
| 275 | // Also T_LNUMBER, e.g.: echo 45; exit -1; and booleans. |
||
| 276 | if ( in_array( $this->tokens[ $i ]['code'], array( T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_MINUS, T_TRUE, T_FALSE, T_NULL ), true ) ) { |
||
| 277 | continue; |
||
| 278 | } |
||
| 279 | |||
| 280 | $watch = false; |
||
| 281 | |||
| 282 | // Allow int/double/bool casted variables. |
||
| 283 | if ( in_array( $this->tokens[ $i ]['code'], array( T_INT_CAST, T_DOUBLE_CAST, T_BOOL_CAST ), true ) ) { |
||
| 284 | $in_cast = true; |
||
| 285 | continue; |
||
| 286 | } |
||
| 287 | |||
| 288 | // Now check that next token is a function call. |
||
| 289 | if ( T_STRING === $this->tokens[ $i ]['code'] ) { |
||
| 290 | |||
| 291 | $ptr = $i; |
||
| 292 | $functionName = $this->tokens[ $i ]['content']; |
||
| 293 | $function_opener = $this->phpcsFile->findNext( array( T_OPEN_PARENTHESIS ), ( $i + 1 ), null, null, null, true ); |
||
| 294 | $is_formatting_function = isset( self::$formattingFunctions[ $functionName ] ); |
||
| 295 | |||
| 296 | if ( $function_opener ) { |
||
| 297 | |||
| 298 | if ( 'array_map' === $functionName ) { |
||
| 299 | |||
| 300 | // Get the first parameter (name of function being used on the array). |
||
| 301 | $mapped_function = $this->phpcsFile->findNext( |
||
| 302 | PHP_CodeSniffer_Tokens::$emptyTokens, |
||
| 303 | ( $function_opener + 1 ), |
||
| 304 | $this->tokens[ $function_opener ]['parenthesis_closer'], |
||
| 305 | true |
||
| 306 | ); |
||
| 307 | |||
| 308 | // If we're able to resolve the function name, do so. |
||
| 309 | View Code Duplication | if ( $mapped_function && T_CONSTANT_ENCAPSED_STRING === $this->tokens[ $mapped_function ]['code'] ) { |
|
| 310 | $functionName = trim( $this->tokens[ $mapped_function ]['content'], '\'' ); |
||
| 311 | $ptr = $mapped_function; |
||
| 312 | } |
||
| 313 | } |
||
| 314 | |||
| 315 | // Skip pointer to after the function. |
||
| 316 | // If this is a formatting function we just skip over the opening |
||
| 317 | // parenthesis. Otherwise we skip all the way to the closing. |
||
| 318 | if ( $is_formatting_function ) { |
||
| 319 | $i = ( $function_opener + 1 ); |
||
| 320 | $watch = true; |
||
| 321 | } else { |
||
| 322 | $i = $this->tokens[ $function_opener ]['parenthesis_closer']; |
||
| 323 | } |
||
| 324 | } |
||
| 325 | |||
| 326 | // If this is a safe function, we don't flag it. |
||
| 327 | if ( |
||
| 328 | $is_formatting_function |
||
| 329 | || isset( self::$autoEscapedFunctions[ $functionName ] ) |
||
| 330 | || isset( self::$escapingFunctions[ $functionName ] ) |
||
| 331 | ) { |
||
| 332 | continue; |
||
| 333 | } |
||
| 334 | |||
| 335 | $content = $functionName; |
||
| 336 | |||
| 337 | } else { |
||
| 338 | $content = $this->tokens[ $i ]['content']; |
||
| 339 | $ptr = $i; |
||
| 340 | } |
||
| 341 | |||
| 342 | $this->phpcsFile->addError( |
||
| 343 | "Expected next thing to be an escaping function (see Codex for 'Data Validation'), not '%s'", |
||
| 344 | $ptr, |
||
| 345 | 'OutputNotEscaped', |
||
| 346 | $content |
||
| 347 | ); |
||
| 348 | } |
||
| 349 | |||
| 350 | return $end_of_statement; |
||
| 351 | |||
| 352 | } // end process() |
||
| 353 | |||
| 355 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.