Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 36 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
DirUsageSniff | |
0.00% |
0 / 36 |
|
0.00% |
0 / 2 |
342 | |
0.00% |
0 / 1 |
register | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
process | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
306 |
1 | <?php |
2 | /** |
3 | * Report error when dirname(__FILE__) is used instead of __DIR__ |
4 | * |
5 | * Fail: dirname( __FILE__ ) |
6 | * Pass: dirname( __FILE__ . "/.." ) |
7 | * Pass: dirname( __FILE__, 2 ) |
8 | * Pass: dirname( joinpaths( __FILE__, ".." ) ) |
9 | * Pass: $abc->dirname( __FILE__ ) |
10 | * Pass: parent::dirname( __FILE__ ) |
11 | */ |
12 | |
13 | namespace MediaWiki\Sniffs\Usage; |
14 | |
15 | use PHP_CodeSniffer\Files\File; |
16 | use PHP_CodeSniffer\Sniffs\Sniff; |
17 | |
18 | class DirUsageSniff implements Sniff { |
19 | |
20 | /** |
21 | * @inheritDoc |
22 | */ |
23 | public function register(): array { |
24 | // As per https://www.mediawiki.org/wiki/Manual:Coding_conventions/PHP#Other |
25 | return [ T_STRING ]; |
26 | } |
27 | |
28 | /** |
29 | * @param File $phpcsFile |
30 | * @param int $stackPtr The current token index. |
31 | * @return void |
32 | */ |
33 | public function process( File $phpcsFile, $stackPtr ) { |
34 | $tokens = $phpcsFile->getTokens(); |
35 | |
36 | // Check if the function is dirname() |
37 | if ( $tokens[$stackPtr]['content'] !== 'dirname' ) { |
38 | return; |
39 | } |
40 | |
41 | // Find the parenthesis for the function |
42 | $nextToken = $phpcsFile->findNext( T_WHITESPACE, $stackPtr + 1, null, true ); |
43 | if ( $nextToken === false |
44 | || $tokens[$nextToken]['code'] !== T_OPEN_PARENTHESIS |
45 | ) { |
46 | return; |
47 | } |
48 | |
49 | // Check if __FILE__ is inside it |
50 | $nextToken = $phpcsFile->findNext( T_WHITESPACE, $nextToken + 1, null, true ); |
51 | if ( $nextToken == false |
52 | || $tokens[$nextToken]['code'] !== T_FILE |
53 | ) { |
54 | return; |
55 | } |
56 | |
57 | // Check if it's a PHP function |
58 | $prevToken = $phpcsFile->findPrevious( T_WHITESPACE, $stackPtr - 1, null, true ); |
59 | if ( $prevToken === false |
60 | || $tokens[$prevToken]['code'] === T_OBJECT_OPERATOR |
61 | || $tokens[$prevToken]['code'] === T_NULLSAFE_OBJECT_OPERATOR |
62 | || $tokens[$prevToken]['code'] === T_DOUBLE_COLON |
63 | || $tokens[$prevToken]['code'] === T_FUNCTION |
64 | || $tokens[$prevToken]['code'] === T_CONST |
65 | ) { |
66 | return; |
67 | } |
68 | |
69 | // Find close parenthesis |
70 | $nextToken = $phpcsFile->findNext( T_WHITESPACE, $nextToken + 1, null, true ); |
71 | if ( $nextToken === false |
72 | || $tokens[$nextToken]['code'] !== T_CLOSE_PARENTHESIS |
73 | ) { |
74 | return; |
75 | } |
76 | |
77 | $fix = $phpcsFile->addFixableError( |
78 | 'Use __DIR__ constant instead of calling dirname(__FILE__)', |
79 | $stackPtr, |
80 | 'FunctionFound' |
81 | ); |
82 | if ( $fix ) { |
83 | $curToken = $stackPtr; |
84 | while ( $curToken <= $nextToken ) { |
85 | if ( $tokens[$curToken]['code'] === T_FILE ) { |
86 | $phpcsFile->fixer->replaceToken( $curToken, '__DIR__' ); |
87 | } else { |
88 | $phpcsFile->fixer->replaceToken( $curToken, '' ); |
89 | } |
90 | $curToken++; |
91 | } |
92 | } |
93 | } |
94 | } |