1<?php
2/**
3 * Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff.
4 *
5 * PHP version 5
6 *
7 * @category  PHP
8 * @package   PHP_CodeSniffer
9 * @author    Greg Sherwood <gsherwood@squiz.net>
10 * @author    Marc McIntyre <mmcintyre@squiz.net>
11 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13 * @link      http://pear.php.net/package/PHP_CodeSniffer
14 */
15
16/**
17 * Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff.
18 *
19 * Ensures all calls to inbuilt PHP functions are lowercase.
20 *
21 * @category  PHP
22 * @package   PHP_CodeSniffer
23 * @author    Greg Sherwood <gsherwood@squiz.net>
24 * @author    Marc McIntyre <mmcintyre@squiz.net>
25 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27 * @version   Release: @package_version@
28 * @link      http://pear.php.net/package/PHP_CodeSniffer
29 */
30class Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff implements PHP_CodeSniffer_Sniff
31{
32
33    /**
34     * String -> int hash map of all php built in function names
35     *
36     * @var array
37     */
38    private $_builtInFunctions;
39
40
41    /**
42     * Construct the LowercasePHPFunctionSniff
43     */
44    public function __construct()
45    {
46
47        $allFunctions            = get_defined_functions();
48        $this->_builtInFunctions = array_flip($allFunctions['internal']);
49
50    }//end __construct()
51
52
53    /**
54     * Returns an array of tokens this test wants to listen for.
55     *
56     * @return array
57     */
58    public function register()
59    {
60        return array(T_STRING);
61
62    }//end register()
63
64
65    /**
66     * Processes this test, when one of its tokens is encountered.
67     *
68     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
69     * @param int                  $stackPtr  The position of the current token in
70     *                                        the stack passed in $tokens.
71     *
72     * @return void
73     */
74    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
75    {
76        $tokens = $phpcsFile->getTokens();
77
78        // Make sure this is a function call.
79        $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
80        if ($next === false) {
81            // Not a function call.
82            return;
83        }
84
85        if ($tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
86            // Not a function call.
87            return;
88        }
89
90        $prev = $phpcsFile->findPrevious(array(T_WHITESPACE, T_BITWISE_AND), ($stackPtr - 1), null, true);
91        if ($tokens[$prev]['code'] === T_FUNCTION) {
92            // Function declaration, not a function call.
93            return;
94        }
95
96        if ($tokens[$prev]['code'] === T_NS_SEPARATOR) {
97            // Namespaced class/function, not an inbuilt function.
98            return;
99        }
100
101        if ($tokens[$prev]['code'] === T_NEW) {
102            // Object creation, not an inbuilt function.
103            return;
104        }
105
106        if ($tokens[$prev]['code'] === T_OBJECT_OPERATOR) {
107            // Not an inbuilt function.
108            return;
109        }
110
111        if ($tokens[$prev]['code'] === T_DOUBLE_COLON) {
112            // Not an inbuilt function.
113            return;
114        }
115
116        // Make sure it is an inbuilt PHP function.
117        // PHP_CodeSniffer can possibly include user defined functions
118        // through the use of vendor/autoload.php.
119        $content = $tokens[$stackPtr]['content'];
120        if (isset($this->_builtInFunctions[strtolower($content)]) === false) {
121            return;
122        }
123
124        if ($content !== strtolower($content)) {
125            $error = 'Calls to inbuilt PHP functions must be lowercase; expected "%s" but found "%s"';
126            $data  = array(
127                      strtolower($content),
128                      $content,
129                     );
130
131            $fix = $phpcsFile->addFixableError($error, $stackPtr, 'CallUppercase', $data);
132            if ($fix === true) {
133                $phpcsFile->fixer->replaceToken($stackPtr, strtolower($content));
134            }
135        }
136
137    }//end process()
138
139
140}//end class
141