Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. FileHeaderSniff.php

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

FileHeaderSniff

Namespace

PHP_CodeSniffer\Standards\PSR12\Sniffs\Files

Code

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
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal