1<?php
2/**
3 * Verifies that operators have valid spacing surrounding them.
4 *
5 * @author    Greg Sherwood <gsherwood@squiz.net>
6 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
7 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8 */
9
10namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace;
11
12use PHP_CodeSniffer\Files\File;
13use PHP_CodeSniffer\Sniffs\Sniff;
14use PHP_CodeSniffer\Util\Tokens;
15
16class LogicalOperatorSpacingSniff implements Sniff
17{
18
19    /**
20     * A list of tokenizers this sniff supports.
21     *
22     * @var array
23     */
24    public $supportedTokenizers = [
25        'PHP',
26        'JS',
27    ];
28
29
30    /**
31     * Returns an array of tokens this test wants to listen for.
32     *
33     * @return array
34     */
35    public function register()
36    {
37        return Tokens::$booleanOperators;
38
39    }//end register()
40
41
42    /**
43     * Processes this sniff, when one of its tokens is encountered.
44     *
45     * @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being checked.
46     * @param int                         $stackPtr  The position of the current token
47     *                                               in the stack passed in $tokens.
48     *
49     * @return void
50     */
51    public function process(File $phpcsFile, $stackPtr)
52    {
53        $tokens = $phpcsFile->getTokens();
54
55        // Check there is one space before the operator.
56        if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) {
57            $error = 'Expected 1 space before logical operator; 0 found';
58            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceBefore');
59            if ($fix === true) {
60                $phpcsFile->fixer->addContentBefore($stackPtr, ' ');
61            }
62        } else {
63            $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
64            if ($tokens[$stackPtr]['line'] === $tokens[$prev]['line']
65                && $tokens[($stackPtr - 1)]['length'] !== 1
66            ) {
67                $found = $tokens[($stackPtr - 1)]['length'];
68                $error = 'Expected 1 space before logical operator; %s found';
69                $data  = [$found];
70                $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'TooMuchSpaceBefore', $data);
71                if ($fix === true) {
72                    $phpcsFile->fixer->replaceToken(($stackPtr - 1), ' ');
73                }
74            }
75        }
76
77        // Check there is one space after the operator.
78        if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) {
79            $error = 'Expected 1 space after logical operator; 0 found';
80            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'NoSpaceAfter');
81            if ($fix === true) {
82                $phpcsFile->fixer->addContent($stackPtr, ' ');
83            }
84        } else {
85            $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
86            if ($tokens[$stackPtr]['line'] === $tokens[$next]['line']
87                && $tokens[($stackPtr + 1)]['length'] !== 1
88            ) {
89                $found = $tokens[($stackPtr + 1)]['length'];
90                $error = 'Expected 1 space after logical operator; %s found';
91                $data  = [$found];
92                $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'TooMuchSpaceAfter', $data);
93                if ($fix === true) {
94                    $phpcsFile->fixer->replaceToken(($stackPtr + 1), ' ');
95                }
96            }
97        }
98
99    }//end process()
100
101
102}//end class
103