1<?php 2/** 3 * PEAR_Sniffs_Files_IncludingFileSniff. 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 * PEAR_Sniffs_Files_IncludingFileSniff. 18 * 19 * Checks that the include_once is used in conditional situations, and 20 * require_once is used elsewhere. Also checks that brackets do not surround 21 * the file being included. 22 * 23 * @category PHP 24 * @package PHP_CodeSniffer 25 * @author Greg Sherwood <gsherwood@squiz.net> 26 * @author Marc McIntyre <mmcintyre@squiz.net> 27 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 28 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 29 * @version Release: @package_version@ 30 * @link http://pear.php.net/package/PHP_CodeSniffer 31 */ 32class PEAR_Sniffs_Files_IncludingFileSniff implements PHP_CodeSniffer_Sniff 33{ 34 35 36 /** 37 * Returns an array of tokens this test wants to listen for. 38 * 39 * @return array 40 */ 41 public function register() 42 { 43 return array( 44 T_INCLUDE_ONCE, 45 T_REQUIRE_ONCE, 46 T_REQUIRE, 47 T_INCLUDE, 48 ); 49 50 }//end register() 51 52 53 /** 54 * Processes this test, when one of its tokens is encountered. 55 * 56 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 57 * @param int $stackPtr The position of the current token in the 58 * stack passed in $tokens. 59 * 60 * @return void 61 */ 62 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 63 { 64 $tokens = $phpcsFile->getTokens(); 65 66 $nextToken = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true); 67 if ($tokens[$nextToken]['code'] === T_OPEN_PARENTHESIS) { 68 $error = '"%s" is a statement not a function; no parentheses are required'; 69 $data = array($tokens[$stackPtr]['content']); 70 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'BracketsNotRequired', $data); 71 if ($fix === true) { 72 $phpcsFile->fixer->beginChangeset(); 73 $phpcsFile->fixer->replaceToken($tokens[$nextToken]['parenthesis_closer'], ''); 74 if ($tokens[($nextToken - 1)]['code'] !== T_WHITESPACE) { 75 $phpcsFile->fixer->replaceToken($nextToken, ' '); 76 } else { 77 $phpcsFile->fixer->replaceToken($nextToken, ''); 78 } 79 80 $phpcsFile->fixer->endChangeset(); 81 } 82 } 83 84 if (count($tokens[$stackPtr]['conditions']) !== 0) { 85 $inCondition = true; 86 } else { 87 $inCondition = false; 88 } 89 90 // Check to see if this including statement is within the parenthesis 91 // of a condition. If that's the case then we need to process it as being 92 // within a condition, as they are checking the return value. 93 if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) { 94 foreach ($tokens[$stackPtr]['nested_parenthesis'] as $left => $right) { 95 if (isset($tokens[$left]['parenthesis_owner']) === true) { 96 $inCondition = true; 97 } 98 } 99 } 100 101 // Check to see if they are assigning the return value of this 102 // including call. If they are then they are probably checking it, so 103 // it's conditional. 104 $previous = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true); 105 if (isset(PHP_CodeSniffer_Tokens::$assignmentTokens[$tokens[$previous]['code']]) === true) { 106 // The have assigned the return value to it, so its conditional. 107 $inCondition = true; 108 } 109 110 $tokenCode = $tokens[$stackPtr]['code']; 111 if ($inCondition === true) { 112 // We are inside a conditional statement. We need an include_once. 113 if ($tokenCode === T_REQUIRE_ONCE) { 114 $error = 'File is being conditionally included; '; 115 $error .= 'use "include_once" instead'; 116 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'UseIncludeOnce'); 117 if ($fix === true) { 118 $phpcsFile->fixer->replaceToken($stackPtr, 'include_once'); 119 } 120 } else if ($tokenCode === T_REQUIRE) { 121 $error = 'File is being conditionally included; '; 122 $error .= 'use "include" instead'; 123 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'UseInclude'); 124 if ($fix === true) { 125 $phpcsFile->fixer->replaceToken($stackPtr, 'include'); 126 } 127 } 128 } else { 129 // We are unconditionally including, we need a require_once. 130 if ($tokenCode === T_INCLUDE_ONCE) { 131 $error = 'File is being unconditionally included; '; 132 $error .= 'use "require_once" instead'; 133 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'UseRequireOnce'); 134 if ($fix === true) { 135 $phpcsFile->fixer->replaceToken($stackPtr, 'require_once'); 136 } 137 } else if ($tokenCode === T_INCLUDE) { 138 $error = 'File is being unconditionally included; '; 139 $error .= 'use "require" instead'; 140 $fix = $phpcsFile->addFixableError($error, $stackPtr, 'UseRequire'); 141 if ($fix === true) { 142 $phpcsFile->fixer->replaceToken($stackPtr, 'require'); 143 } 144 } 145 }//end if 146 147 }//end process() 148 149 150}//end class 151