function FileHeaderSniff::processHeaderLines
Check the spacing and grouping of the statements inside each header block.
Parameters
\PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.:
array $headerLines Header information, as sourced: from getHeaderLines().
Return value
void
1 call to FileHeaderSniff::processHeaderLines()
- FileHeaderSniff::process in vendor/
squizlabs/ php_codesniffer/ src/ Standards/ PSR12/ Sniffs/ Files/ FileHeaderSniff.php - Processes this sniff when one of its tokens is encountered.
File
-
vendor/
squizlabs/ php_codesniffer/ src/ Standards/ PSR12/ Sniffs/ Files/ FileHeaderSniff.php, line 289
Class
Namespace
PHP_CodeSniffer\Standards\PSR12\Sniffs\FilesCode
public function processHeaderLines(File $phpcsFile, $headerLines) {
$tokens = $phpcsFile->getTokens();
$found = [];
foreach ($headerLines as $i => $line) {
if (isset($headerLines[$i + 1]) === false || $headerLines[$i + 1]['type'] !== $line['type']) {
// We're at the end of the current header block.
// Make sure there is a single blank line after
// this block.
$next = $phpcsFile->findNext(T_WHITESPACE, $line['end'] + 1, null, true);
if ($next !== false && $tokens[$next]['line'] !== $tokens[$line['end']]['line'] + 2) {
$error = 'Header blocks must be separated by a single blank line';
$fix = $phpcsFile->addFixableError($error, $line['end'], 'SpacingAfterBlock');
if ($fix === true) {
if ($tokens[$next]['line'] === $tokens[$line['end']]['line']) {
$phpcsFile->fixer
->addContentBefore($next, $phpcsFile->eolChar . $phpcsFile->eolChar);
}
else {
if ($tokens[$next]['line'] === $tokens[$line['end']]['line'] + 1) {
$phpcsFile->fixer
->addNewline($line['end']);
}
else {
$phpcsFile->fixer
->beginChangeset();
for ($i = $line['end'] + 1; $i < $next; $i++) {
if ($tokens[$i]['line'] === $tokens[$line['end']]['line'] + 2) {
break;
}
$phpcsFile->fixer
->replaceToken($i, '');
}
$phpcsFile->fixer
->endChangeset();
}
}
}
//end if
}
//end if
// Make sure we haven't seen this next block before.
if (isset($headerLines[$i + 1]) === true && isset($found[$headerLines[$i + 1]['type']]) === true) {
$error = 'Similar statements must be grouped together inside header blocks; ';
$error .= 'the first "%s" statement was found on line %s';
$data = [
$headerLines[$i + 1]['type'],
$tokens[$found[$headerLines[$i + 1]['type']]['start']]['line'],
];
$phpcsFile->addError($error, $headerLines[$i + 1]['start'], 'IncorrectGrouping', $data);
}
}
else {
if ($headerLines[$i + 1]['type'] === $line['type']) {
// Still in the same block, so make sure there is no
// blank line after this statement.
$next = $phpcsFile->findNext(T_WHITESPACE, $line['end'] + 1, null, true);
if ($tokens[$next]['line'] > $tokens[$line['end']]['line'] + 1) {
$error = 'Header blocks must not contain blank lines';
$fix = $phpcsFile->addFixableError($error, $line['end'], 'SpacingInsideBlock');
if ($fix === true) {
$phpcsFile->fixer
->beginChangeset();
for ($i = $line['end'] + 1; $i < $next; $i++) {
if ($tokens[$i]['line'] === $tokens[$line['end']]['line']) {
continue;
}
if ($tokens[$i]['line'] === $tokens[$next]['line']) {
break;
}
$phpcsFile->fixer
->replaceToken($i, '');
}
$phpcsFile->fixer
->endChangeset();
}
}
}
}
//end if
if (isset($found[$line['type']]) === false) {
$found[$line['type']] = $line;
}
}
//end foreach
/*
Next, check that the order of the header blocks
is correct:
Opening php tag.
File-level docblock.
One or more declare statements.
The namespace declaration of the file.
One or more class-based use import statements.
One or more function-based use import statements.
One or more constant-based use import statements.
*/
$blockOrder = [
'tag' => 'opening PHP tag',
'docblock' => 'file-level docblock',
'declare' => 'declare statements',
'namespace' => 'namespace declaration',
'use' => 'class-based use imports',
'use function' => 'function-based use imports',
'use const' => 'constant-based use imports',
];
foreach (array_keys($found) as $type) {
if ($type === 'tag') {
// The opening tag is always in the correct spot.
continue;
}
do {
$orderedType = next($blockOrder);
} while ($orderedType !== false && key($blockOrder) !== $type);
if ($orderedType === false) {
// We didn't find the block type in the rest of the
// ordered array, so it is out of place.
// Error and reset the array to the correct position
// so we can check the next block.
reset($blockOrder);
$prevValidType = 'tag';
do {
$orderedType = next($blockOrder);
if (isset($found[key($blockOrder)]) === true && key($blockOrder) !== $type) {
$prevValidType = key($blockOrder);
}
} while ($orderedType !== false && key($blockOrder) !== $type);
$error = 'The %s must follow the %s in the file header';
$data = [
$blockOrder[$type],
$blockOrder[$prevValidType],
];
$phpcsFile->addError($error, $found[$type]['start'], 'IncorrectOrder', $data);
}
//end if
}
//end foreach
}