1<?php
2/**
3 * Generic_Sniffs_Debug_JSHintSniff.
4 *
5 * PHP version 5
6 *
7 * @category  PHP
8 * @package   PHP_CodeSniffer
9 * @author    Greg Sherwood <gsherwood@squiz.net>
10 * @author    Alexander Wei§ <aweisswa@gmx.de>
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 * Generic_Sniffs_Debug_JSHintSniff.
18 *
19 * Runs jshint.js on the file.
20 *
21 * @category  PHP
22 * @package   PHP_CodeSniffer
23 * @author    Greg Sherwood <gsherwood@squiz.net>
24 * @author    Alexander Wei§ <aweisswa@gmx.de>
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 Generic_Sniffs_Debug_JSHintSniff implements PHP_CodeSniffer_Sniff
31{
32
33    /**
34     * A list of tokenizers this sniff supports.
35     *
36     * @var array
37     */
38    public $supportedTokenizers = array('JS');
39
40
41    /**
42     * Returns the token types that this sniff is interested in.
43     *
44     * @return int[]
45     */
46    public function register()
47    {
48        return array(T_OPEN_TAG);
49
50    }//end register()
51
52
53    /**
54     * Processes the tokens that this sniff is interested in.
55     *
56     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
57     * @param int                  $stackPtr  The position in the stack where
58     *                                        the token was found.
59     *
60     * @return void
61     * @throws PHP_CodeSniffer_Exception If jshint.js could not be run
62     */
63    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
64    {
65        $fileName = $phpcsFile->getFilename();
66
67        $rhinoPath  = PHP_CodeSniffer::getConfigData('rhino_path');
68        $jshintPath = PHP_CodeSniffer::getConfigData('jshint_path');
69        if ($rhinoPath === null || $jshintPath === null) {
70            return;
71        }
72
73        $rhinoPath  = escapeshellcmd($rhinoPath);
74        $jshintPath = escapeshellcmd($jshintPath);
75
76        $cmd = "$rhinoPath \"$jshintPath\" ".escapeshellarg($fileName);
77        $msg = exec($cmd, $output, $retval);
78
79        if (is_array($output) === true) {
80            foreach ($output as $finding) {
81                $matches    = array();
82                $numMatches = preg_match('/^(.+)\(.+:([0-9]+).*:[0-9]+\)$/', $finding, $matches);
83                if ($numMatches === 0) {
84                    continue;
85                }
86
87                $line    = (int) $matches[2];
88                $message = 'jshint says: '.trim($matches[1]);
89                $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool');
90            }
91        }
92
93        // Ignore the rest of the file.
94        return ($phpcsFile->numTokens + 1);
95
96    }//end process()
97
98
99}//end class
100