1<?php
2/**
3 * Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff.
4 *
5 * PHP version 5
6 *
7 * @category  PHP
8 * @package   PHP_CodeSniffer
9 * @author    Greg Sherwood <gsherwood@squiz.net>
10 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12 * @link      http://pear.php.net/package/PHP_CodeSniffer
13 */
14
15/**
16 * Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff.
17 *
18 * Ensure there is a single space before the opening brace in a class definition
19 * and the content starts on the next line.
20 *
21 * @category  PHP
22 * @package   PHP_CodeSniffer
23 * @author    Greg Sherwood <gsherwood@squiz.net>
24 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
25 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
26 * @version   Release: @package_version@
27 * @link      http://pear.php.net/package/PHP_CodeSniffer
28 */
29class Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff implements PHP_CodeSniffer_Sniff
30{
31
32    /**
33     * A list of tokenizers this sniff supports.
34     *
35     * @var array
36     */
37    public $supportedTokenizers = array('CSS');
38
39
40    /**
41     * Returns the token types that this sniff is interested in.
42     *
43     * @return int[]
44     */
45    public function register()
46    {
47        return array(T_OPEN_CURLY_BRACKET);
48
49    }//end register()
50
51
52    /**
53     * Processes the tokens that this sniff is interested in.
54     *
55     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
56     * @param int                  $stackPtr  The position in the stack where
57     *                                        the token was found.
58     *
59     * @return void
60     */
61    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
62    {
63        $tokens = $phpcsFile->getTokens();
64
65        if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) {
66            $error = 'Expected 1 space before opening brace of class definition; 0 found';
67            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'NoneBefore');
68            if ($fix === true) {
69                $phpcsFile->fixer->addContentBefore($stackPtr, ' ');
70            }
71        } else {
72            $content = $tokens[($stackPtr - 1)]['content'];
73            if ($content !== ' ') {
74                if ($tokens[($stackPtr - 1)]['line'] < $tokens[$stackPtr]['line']) {
75                    $length = 'newline';
76                } else {
77                    $length = strlen($content);
78                    if ($length === 1) {
79                        $length = 'tab';
80                    }
81                }
82
83                $error = 'Expected 1 space before opening brace of class definition; %s found';
84                $data  = array($length);
85                $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'Before', $data);
86                if ($fix === true) {
87                    $phpcsFile->fixer->replaceToken(($stackPtr - 1), ' ');
88                }
89            }
90        }//end if
91
92        $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true);
93        if ($next === false) {
94            return;
95        }
96
97        // Check for nested class definitions.
98        $nested = false;
99        $found  = $phpcsFile->findNext(
100            T_OPEN_CURLY_BRACKET,
101            ($stackPtr + 1),
102            $tokens[$stackPtr]['bracket_closer']
103        );
104
105        if ($found !== false) {
106            $nested = true;
107        }
108
109        if ($tokens[$next]['line'] === $tokens[$stackPtr]['line']) {
110            $error = 'Opening brace should be the last content on the line';
111            $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'ContentBefore');
112            if ($fix === true) {
113                $phpcsFile->fixer->addNewline($stackPtr);
114            }
115        } else {
116            $foundLines = ($tokens[$next]['line'] - $tokens[$stackPtr]['line'] - 1);
117            if ($nested === true) {
118                if ($foundLines !== 1) {
119                    $error = 'Expected 1 blank line after opening brace of nesting class definition; %s found';
120                    $data  = array($foundLines);
121                    $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'AfterNesting', $data);
122
123                    if ($fix === true) {
124                        if ($foundLines === 0) {
125                            $phpcsFile->fixer->addNewline($stackPtr);
126                        } else {
127                            $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
128                            $phpcsFile->fixer->beginChangeset();
129                            for ($i = ($stackPtr + 1); $i < ($next + 1); $i++) {
130                                $phpcsFile->fixer->replaceToken($i, '');
131                            }
132
133                            $phpcsFile->fixer->addNewline($stackPtr);
134                            $phpcsFile->fixer->endChangeset();
135                        }
136                    }
137                }//end if
138            }//end if
139        }//end if
140
141    }//end process()
142
143
144}//end class
145