GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( ebb7bf...0a5ff4 )
by Chris
02:41 queued 11s
created

PHP_CodeSniffer_CLI::process()   F

Complexity

Conditions 20
Paths 2066

Size

Total Lines 128
Code Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 73
nc 2066
nop 1
dl 0
loc 128
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * A class to process command line phpcs scripts.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Greg Sherwood <[email protected]>
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
error_reporting(E_ALL | E_STRICT);
16
17
// Make sure version id constant is available.
18
if (defined('PHP_VERSION_ID') === false) {
19
    $version = explode('.', PHP_VERSION);
20
    define('PHP_VERSION_ID', (int) (($version[0] * 10000) + ($version[1] * 100) + $version[2]));
21
    unset($version);
22
}
23
24
// Make sure that we autoload all dependencies if running via Composer.
25
if (PHP_VERSION_ID >= 50302) {
26
    if (file_exists($a = dirname(__FILE__).'/../../../autoload.php') === true) {
27
        include_once $a;
28
    } else if (file_exists($a = dirname(__FILE__).'/../vendor/autoload.php') === true) {
29
        include_once $a;
30
    }
31
}
32
33
if (file_exists($a = dirname(__FILE__).'/../CodeSniffer.php') === true) {
34
    // Running from a git clone.
35
    include_once $a;
36
} else {
37
    // PEAR installed.
38
    include_once 'PHP/CodeSniffer.php';
39
}
40
41
/**
42
 * A class to process command line phpcs scripts.
43
 *
44
 * @category  PHP
45
 * @package   PHP_CodeSniffer
46
 * @author    Greg Sherwood <[email protected]>
47
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
48
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
49
 * @version   Release: @package_version@
50
 * @link      http://pear.php.net/package/PHP_CodeSniffer
51
 */
52
class PHP_CodeSniffer_CLI
53
{
54
55
    /**
56
     * An array of all values specified on the command line.
57
     *
58
     * @var array
59
     */
60
    protected $values = array();
61
62
    /**
63
     * The minimum severity level errors must have to be displayed.
64
     *
65
     * @var bool
66
     */
67
    public $errorSeverity = 0;
68
69
    /**
70
     * The minimum severity level warnings must have to be displayed.
71
     *
72
     * @var bool
73
     */
74
    public $warningSeverity = 0;
75
76
    /**
77
     * Whether or not to kill the process when an unknown command line arg is found.
78
     *
79
     * If FALSE, arguments that are not command line options or file/directory paths
80
     * will be ignored and execution will continue.
81
     *
82
     * @var bool
83
     */
84
    public $dieOnUnknownArg = true;
85
86
    /**
87
     * An array of the current command line arguments we are processing.
88
     *
89
     * @var array
90
     */
91
    private $_cliArgs = array();
92
93
94
    /**
95
     * Run the PHPCS script.
96
     *
97
     * @return array
98
     */
99
    public function runphpcs()
100
    {
101
        if (defined('PHP_CODESNIFFER_CBF') === false) {
102
            define('PHP_CODESNIFFER_CBF', false);
103
        }
104
105
        if (is_file(dirname(__FILE__).'/../CodeSniffer/Reporting.php') === true) {
106
            include_once dirname(__FILE__).'/../CodeSniffer/Reporting.php';
107
        } else {
108
            include_once 'PHP/CodeSniffer/Reporting.php';
109
        }
110
111
        PHP_CodeSniffer_Reporting::startTiming();
112
        $this->checkRequirements();
113
        $numErrors = $this->process();
114
        if ($numErrors === 0) {
115
            exit(0);
116
        } else {
117
            exit(1);
118
        }
119
120
    }//end runphpcs()
121
122
123
    /**
124
     * Run the PHPCBF script.
125
     *
126
     * @return array
127
     */
128
    public function runphpcbf()
129
    {
130
        if (defined('PHP_CODESNIFFER_CBF') === false) {
131
            define('PHP_CODESNIFFER_CBF', true);
132
        }
133
134
        if (is_file(dirname(__FILE__).'/../CodeSniffer/Reporting.php') === true) {
135
            include_once dirname(__FILE__).'/../CodeSniffer/Reporting.php';
136
        } else {
137
            include_once 'PHP/CodeSniffer/Reporting.php';
138
        }
139
140
        PHP_CodeSniffer_Reporting::startTiming();
141
        $this->checkRequirements();
142
143
        $this->dieOnUnknownArg = false;
144
145
        // Override some of the command line settings that might break the fixes.
146
        $cliValues = $this->getCommandLineValues();
147
        $cliValues['verbosity']    = 0;
148
        $cliValues['showProgress'] = false;
149
        $cliValues['generator']    = '';
150
        $cliValues['explain']      = false;
151
        $cliValues['interactive']  = false;
152
        $cliValues['showSources']  = false;
153
        $cliValues['reportFile']   = null;
154
        $cliValues['reports']      = array();
155
156
        $suffix = '';
157
        if (isset($cliValues['suffix']) === true) {
158
            $suffix = $cliValues['suffix'];
159
        }
160
161
        $allowPatch = true;
162
        if (isset($cliValues['no-patch']) === true || empty($cliValues['files']) === true) {
163
            // They either asked for this,
164
            // or they are using STDIN, which can't use diff.
165
            $allowPatch = false;
166
        }
167
168
        if ($suffix === '' && $allowPatch === true) {
169
            // Using the diff/patch tools.
170
            $diffFile = getcwd().'/phpcbf-fixed.diff';
171
            $cliValues['reports'] = array('diff' => $diffFile);
172
            if (file_exists($diffFile) === true) {
173
                unlink($diffFile);
174
            }
175
        } else {
176
            // Replace the file without the patch command
177
            // or writing to a file with a new suffix.
178
            $cliValues['reports']       = array('cbf' => null);
179
            $cliValues['phpcbf-suffix'] = $suffix;
180
        }
181
182
        $numErrors = $this->process($cliValues);
183
184
        if ($suffix === '' && $allowPatch === true) {
185
            if (file_exists($diffFile) === false) {
186
                // Nothing to fix.
187
                if ($numErrors === 0) {
188
                    // And no errors reported.
189
                    $exit = 0;
190
                } else {
191
                    // Errors we can't fix.
192
                    $exit = 2;
193
                }
194
            } else {
195
                if (filesize($diffFile) < 10) {
196
                    // Empty or bad diff file.
197
                    if ($numErrors === 0) {
198
                        // And no errors reported.
199
                        $exit = 0;
200
                    } else {
201
                        // Errors we can't fix.
202
                        $exit = 2;
203
                    }
204
                } else {
205
                    $cmd    = "patch -p0 -ui \"$diffFile\"";
206
                    $output = array();
207
                    $retVal = null;
208
                    exec($cmd, $output, $retVal);
209
210
                    if ($retVal === 0) {
211
                        // Everything went well.
212
                        $filesPatched = count($output);
213
                        echo "Patched $filesPatched file";
214
                        if ($filesPatched > 1) {
215
                            echo 's';
216
                        }
217
218
                        echo PHP_EOL;
219
                        $exit = 1;
220
                    } else {
221
                        print_r($output);
222
                        echo "Returned: $retVal".PHP_EOL;
223
                        $exit = 3;
224
                    }
225
                }//end if
226
227
                unlink($diffFile);
228
            }//end if
229
        } else {
230
            // File are being patched manually, so we can't tell
231
            // how many errors were fixed.
232
            $exit = 1;
233
        }//end if
234
235
        if ($exit === 0) {
236
            echo 'No fixable errors were found'.PHP_EOL;
237
        } else if ($exit === 2) {
238
            echo 'PHPCBF could not fix all the errors found'.PHP_EOL;
239
        }
240
241
        PHP_CodeSniffer_Reporting::printRunTime();
242
        exit($exit);
243
244
    }//end runphpcbf()
245
246
247
    /**
248
     * Exits if the minimum requirements of PHP_CodSniffer are not met.
249
     *
250
     * @return array
251
     */
252
    public function checkRequirements()
253
    {
254
        // Check the PHP version.
255
        if (PHP_VERSION_ID < 50102) {
256
            echo 'ERROR: PHP_CodeSniffer requires PHP version 5.1.2 or greater.'.PHP_EOL;
257
            exit(2);
258
        }
259
260
        if (extension_loaded('tokenizer') === false) {
261
            echo 'ERROR: PHP_CodeSniffer requires the tokenizer extension to be enabled.'.PHP_EOL;
262
            exit(2);
263
        }
264
265
    }//end checkRequirements()
266
267
268
    /**
269
     * Get a list of default values for all possible command line arguments.
270
     *
271
     * @return array
272
     */
273
    public function getDefaults()
274
    {
275
        if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
276
            return array();
277
        }
278
279
        // The default values for config settings.
280
        $defaults['files']           = array();
281
        $defaults['standard']        = null;
282
        $defaults['verbosity']       = 0;
283
        $defaults['interactive']     = false;
284
        $defaults['colors']          = false;
285
        $defaults['explain']         = false;
286
        $defaults['local']           = false;
287
        $defaults['showSources']     = false;
288
        $defaults['extensions']      = array();
289
        $defaults['sniffs']          = array();
290
        $defaults['exclude']         = array();
291
        $defaults['ignored']         = array();
292
        $defaults['reportFile']      = null;
293
        $defaults['generator']       = '';
294
        $defaults['reports']         = array();
295
        $defaults['bootstrap']       = array();
296
        $defaults['errorSeverity']   = null;
297
        $defaults['warningSeverity'] = null;
298
        $defaults['stdin']           = null;
299
        $defaults['stdinPath']       = '';
300
301
        $reportFormat = PHP_CodeSniffer::getConfigData('report_format');
302
        if ($reportFormat !== null) {
303
            $defaults['reports'][$reportFormat] = null;
304
        }
305
306
        $tabWidth = PHP_CodeSniffer::getConfigData('tab_width');
307
        if ($tabWidth === null) {
308
            $defaults['tabWidth'] = 0;
309
        } else {
310
            $defaults['tabWidth'] = (int) $tabWidth;
311
        }
312
313
        $encoding = PHP_CodeSniffer::getConfigData('encoding');
314
        if ($encoding === null) {
315
            $defaults['encoding'] = 'iso-8859-1';
316
        } else {
317
            $defaults['encoding'] = strtolower($encoding);
318
        }
319
320
        $severity = PHP_CodeSniffer::getConfigData('severity');
321
        if ($severity !== null) {
322
            $defaults['errorSeverity']   = (int) $severity;
323
            $defaults['warningSeverity'] = (int) $severity;
324
        }
325
326
        $severity = PHP_CodeSniffer::getConfigData('error_severity');
327
        if ($severity !== null) {
328
            $defaults['errorSeverity'] = (int) $severity;
329
        }
330
331
        $severity = PHP_CodeSniffer::getConfigData('warning_severity');
332
        if ($severity !== null) {
333
            $defaults['warningSeverity'] = (int) $severity;
334
        }
335
336
        $showWarnings = PHP_CodeSniffer::getConfigData('show_warnings');
337
        if ($showWarnings !== null) {
338
            $showWarnings = (bool) $showWarnings;
339
            if ($showWarnings === false) {
340
                $defaults['warningSeverity'] = 0;
341
            }
342
        }
343
344
        $reportWidth = PHP_CodeSniffer::getConfigData('report_width');
345
        if ($reportWidth !== null) {
346
            $defaults['reportWidth'] = $this->_validateReportWidth($reportWidth);
347
        } else {
348
            // Use function defaults.
349
            $defaults['reportWidth'] = null;
350
        }
351
352
        $showProgress = PHP_CodeSniffer::getConfigData('show_progress');
353
        if ($showProgress === null) {
354
            $defaults['showProgress'] = false;
355
        } else {
356
            $defaults['showProgress'] = (bool) $showProgress;
357
        }
358
359
        $quiet = PHP_CodeSniffer::getConfigData('quiet');
360
        if ($quiet === null) {
361
            $defaults['quiet'] = false;
362
        } else {
363
            $defaults['quiet'] = (bool) $quiet;
364
        }
365
366
        $colors = PHP_CodeSniffer::getConfigData('colors');
367
        if ($colors === null) {
368
            $defaults['colors'] = false;
369
        } else {
370
            $defaults['colors'] = (bool) $colors;
371
        }
372
373
        if (PHP_CodeSniffer::isPharFile(dirname(dirname(__FILE__))) === true) {
374
            // If this is a phar file, check for the standard in the config.
375
            $standard = PHP_CodeSniffer::getConfigData('standard');
376
            if ($standard !== null) {
377
                $defaults['standard'] = $standard;
378
            }
379
        }
380
381
        return $defaults;
382
383
    }//end getDefaults()
384
385
386
    /**
387
     * Gets the processed command line values.
388
     *
389
     * If the values have not yet been set, the values will be sourced
390
     * from the command line arguments.
391
     *
392
     * @return array
393
     */
394
    public function getCommandLineValues()
395
    {
396
        if (empty($this->values) === false) {
397
            return $this->values;
398
        }
399
400
        $args = $_SERVER['argv'];
401
        array_shift($args);
402
403
        $this->setCommandLineValues($args);
404
405
        // Check for content on STDIN.
406
        $handle = fopen('php://stdin', 'r');
407
        if (stream_set_blocking($handle, false) === true) {
408
            $fileContents = '';
409
            while (($line = fgets($handle)) !== false) {
410
                $fileContents .= $line;
411
                usleep(10);
412
            }
413
414
            stream_set_blocking($handle, true);
415
            fclose($handle);
416
            if (trim($fileContents) !== '') {
417
                $this->values['stdin'] = $fileContents;
418
            }
419
        }
420
421
        return $this->values;
422
423
    }//end getCommandLineValues()
424
425
426
    /**
427
     * Set the command line values.
428
     *
429
     * @param array $args An array of command line arguments to process.
430
     *
431
     * @return void
432
     */
433
    public function setCommandLineValues($args)
434
    {
435
        if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
436
            $this->values = array(
437
                             'stdin' => null,
438
                             'quiet' => true,
439
                            );
440
        } else if (empty($this->values) === true) {
441
            $this->values = $this->getDefaults();
442
        }
443
444
        $this->_cliArgs = $args;
445
        $numArgs        = count($args);
446
447
        for ($i = 0; $i < $numArgs; $i++) {
448
            $arg = $this->_cliArgs[$i];
449
            if ($arg === '') {
450
                continue;
451
            }
452
453
            if ($arg{0} === '-') {
454
                if ($arg === '-' || $arg === '--') {
455
                    // Empty argument, ignore it.
456
                    continue;
457
                }
458
459
                if ($arg{1} === '-') {
460
                    $this->processLongArgument(substr($arg, 2), $i);
461
                } else {
462
                    $switches = str_split($arg);
463
                    foreach ($switches as $switch) {
464
                        if ($switch === '-') {
465
                            continue;
466
                        }
467
468
                        $this->processShortArgument($switch, $i);
469
                    }
470
                }
471
            } else {
472
                $this->processUnknownArgument($arg, $i);
473
            }//end if
474
        }//end for
475
476
    }//end setCommandLineValues()
477
478
479
    /**
480
     * Processes a short (-e) command line argument.
481
     *
482
     * @param string $arg The command line argument.
483
     * @param int    $pos The position of the argument on the command line.
484
     *
485
     * @return void
486
     */
487
    public function processShortArgument($arg, $pos)
488
    {
489
        switch ($arg) {
490
        case 'h':
491
        case '?':
492
            $this->printUsage();
493
            exit(0);
494
        case 'i' :
495
            $this->printInstalledStandards();
496
            exit(0);
497
        case 'v' :
498
            if ($this->values['quiet'] === true) {
499
                // Ignore when quiet mode is enabled.
500
                break;
501
            }
502
503
            if (isset($this->values['verbosity']) === false) {
504
                $this->values['verbosity'] = 1;
505
            } else {
506
                $this->values['verbosity']++;
507
            }
508
            break;
509
        case 'l' :
510
            $this->values['local'] = true;
511
            break;
512
        case 's' :
513
            $this->values['showSources'] = true;
514
            break;
515
        case 'a' :
516
            $this->values['interactive'] = true;
517
            break;
518
        case 'e':
519
            $this->values['explain'] = true;
520
            break;
521
        case 'p' :
522
            if ($this->values['quiet'] === true) {
523
                // Ignore when quiet mode is enabled.
524
                break;
525
            }
526
527
            $this->values['showProgress'] = true;
528
            break;
529
        case 'q' :
530
            // Quiet mode disables a few other settings as well.
531
            $this->values['quiet']        = true;
532
            $this->values['showProgress'] = false;
533
            $this->values['verbosity']    = 0;
534
            break;
535
        case 'd' :
536
            $ini = explode('=', $this->_cliArgs[($pos + 1)]);
537
            $this->_cliArgs[($pos + 1)] = '';
538
            if (isset($ini[1]) === true) {
539
                ini_set($ini[0], $ini[1]);
540
            } else {
541
                ini_set($ini[0], true);
542
            }
543
            break;
544
        case 'n' :
545
            $this->values['warningSeverity'] = 0;
546
            break;
547
        case 'w' :
548
            $this->values['warningSeverity'] = null;
549
            break;
550
        default:
551
            if ($this->dieOnUnknownArg === false) {
552
                $this->values[$arg] = $arg;
553
            } else {
554
                $this->processUnknownArgument('-'.$arg, $pos);
555
            }
556
        }//end switch
557
558
    }//end processShortArgument()
559
560
561
    /**
562
     * Processes a long (--example) command line argument.
563
     *
564
     * @param string $arg The command line argument.
565
     * @param int    $pos The position of the argument on the command line.
566
     *
567
     * @return void
568
     */
569
    public function processLongArgument($arg, $pos)
570
    {
571
        switch ($arg) {
572
        case 'help':
573
            $this->printUsage();
574
            exit(0);
575
        case 'version':
576
            echo 'PHP_CodeSniffer version '.PHP_CodeSniffer::VERSION.' ('.PHP_CodeSniffer::STABILITY.') ';
577
            echo 'by Squiz (http://www.squiz.net)'.PHP_EOL;
578
            exit(0);
579
        case 'colors':
580
            $this->values['colors'] = true;
581
            break;
582
        case 'no-colors':
583
            $this->values['colors'] = false;
584
            break;
585
        case 'config-set':
586
            if (isset($this->_cliArgs[($pos + 1)]) === false
587
                || isset($this->_cliArgs[($pos + 2)]) === false
588
            ) {
589
                echo 'ERROR: Setting a config option requires a name and value'.PHP_EOL.PHP_EOL;
590
                $this->printUsage();
591
                exit(0);
592
            }
593
594
            $key     = $this->_cliArgs[($pos + 1)];
595
            $value   = $this->_cliArgs[($pos + 2)];
596
            $current = PHP_CodeSniffer::getConfigData($key);
597
598
            try {
599
                PHP_CodeSniffer::setConfigData($key, $value);
600
            } catch (Exception $e) {
601
                echo $e->getMessage().PHP_EOL;
602
                exit(2);
603
            }
604
605
            if ($current === null) {
606
                echo "Config value \"$key\" added successfully".PHP_EOL;
607
            } else {
608
                echo "Config value \"$key\" updated successfully; old value was \"$current\"".PHP_EOL;
609
            }
610
            exit(0);
611
        case 'config-delete':
612
            if (isset($this->_cliArgs[($pos + 1)]) === false) {
613
                echo 'ERROR: Deleting a config option requires the name of the option'.PHP_EOL.PHP_EOL;
614
                $this->printUsage();
615
                exit(0);
616
            }
617
618
            $key     = $this->_cliArgs[($pos + 1)];
619
            $current = PHP_CodeSniffer::getConfigData($key);
620
            if ($current === null) {
621
                echo "Config value \"$key\" has not been set".PHP_EOL;
622
            } else {
623
                try {
624
                    PHP_CodeSniffer::setConfigData($key, null);
625
                } catch (Exception $e) {
626
                    echo $e->getMessage().PHP_EOL;
627
                    exit(2);
628
                }
629
630
                echo "Config value \"$key\" removed successfully; old value was \"$current\"".PHP_EOL;
631
            }
632
            exit(0);
633
        case 'config-show':
634
            $data = PHP_CodeSniffer::getAllConfigData();
635
            $this->printConfigData($data);
636
            exit(0);
637
        case 'runtime-set':
638
            if (isset($this->_cliArgs[($pos + 1)]) === false
639
                || isset($this->_cliArgs[($pos + 2)]) === false
640
            ) {
641
                echo 'ERROR: Setting a runtime config option requires a name and value'.PHP_EOL.PHP_EOL;
642
                $this->printUsage();
643
                exit(0);
644
            }
645
646
            $key   = $this->_cliArgs[($pos + 1)];
647
            $value = $this->_cliArgs[($pos + 2)];
648
            $this->_cliArgs[($pos + 1)] = '';
649
            $this->_cliArgs[($pos + 2)] = '';
650
            PHP_CodeSniffer::setConfigData($key, $value, true);
651
            break;
652
        default:
653
            if (substr($arg, 0, 7) === 'sniffs=') {
654
                $sniffs = explode(',', substr($arg, 7));
655
                foreach ($sniffs as $sniff) {
656
                    if (substr_count($sniff, '.') !== 2) {
657
                        echo 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
658
                        $this->printUsage();
659
                        exit(2);
660
                    }
661
                }
662
663
                $this->values['sniffs'] = $sniffs;
664
            } else if (substr($arg, 0, 8) === 'exclude=') {
665
                $sniffs = explode(',', substr($arg, 8));
666
                foreach ($sniffs as $sniff) {
667
                    if (substr_count($sniff, '.') !== 2) {
668
                        echo 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
669
                        $this->printUsage();
670
                        exit(2);
671
                    }
672
                }
673
674
                $this->values['exclude'] = $sniffs;
675
            } else if (substr($arg, 0, 10) === 'bootstrap=') {
676
                $files = explode(',', substr($arg, 10));
677
                foreach ($files as $file) {
678
                    $path = PHP_CodeSniffer::realpath($file);
679
                    if ($path === false) {
680
                        echo 'ERROR: The specified bootstrap file "'.$file.'" does not exist'.PHP_EOL.PHP_EOL;
681
                        $this->printUsage();
682
                        exit(2);
683
                    }
684
685
                    $this->values['bootstrap'][] = $path;
686
                }
687
            } else if (substr($arg, 0, 10) === 'file-list=') {
688
                $fileList = substr($arg, 10);
689
                $path     = PHP_CodeSniffer::realpath($fileList);
690
                if ($path === false) {
691
                    echo 'ERROR: The specified file list "'.$file.'" does not exist'.PHP_EOL.PHP_EOL;
692
                    $this->printUsage();
693
                    exit(2);
694
                }
695
696
                $files = file($path);
697
                foreach ($files as $inputFile) {
698
                    $inputFile = trim($inputFile);
699
700
                    // Skip empty lines.
701
                    if ($inputFile === '') {
702
                        continue;
703
                    }
704
705
                    $realFile = PHP_CodeSniffer::realpath($inputFile);
706
                    if ($realFile === false) {
707
                        echo 'ERROR: The specified file "'.$inputFile.'" does not exist'.PHP_EOL.PHP_EOL;
708
                        $this->printUsage();
709
                        exit(2);
710
                    }
711
712
                    $this->values['files'][] = $realFile;
713
                }
714
            } else if (substr($arg, 0, 11) === 'stdin-path=') {
715
                $this->values['stdinPath'] = PHP_CodeSniffer::realpath(substr($arg, 11));
716
717
                // It may not exist and return false instead, so just use whatever they gave us.
718
                if ($this->values['stdinPath'] === false) {
719
                    $this->values['stdinPath'] = trim(substr($arg, 11));
720
                }
721
            } else if (substr($arg, 0, 12) === 'report-file=') {
722
                $this->values['reportFile'] = PHP_CodeSniffer::realpath(substr($arg, 12));
723
724
                // It may not exist and return false instead.
725
                if ($this->values['reportFile'] === false) {
726
                    $this->values['reportFile'] = substr($arg, 12);
727
728
                    $dir = dirname($this->values['reportFile']);
729
                    if (is_dir($dir) === false) {
730
                        echo 'ERROR: The specified report file path "'.$this->values['reportFile'].'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
731
                        $this->printUsage();
732
                        exit(2);
733
                    }
734
735
                    if ($dir === '.') {
736
                        // Passed report file is a file in the current directory.
737
                        $this->values['reportFile'] = getcwd().'/'.basename($this->values['reportFile']);
738
                    } else {
739
                        if ($dir{0} === '/') {
740
                            // An absolute path.
741
                            $dir = PHP_CodeSniffer::realpath($dir);
742
                        } else {
743
                            $dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
744
                        }
745
746
                        if ($dir !== false) {
747
                            // Report file path is relative.
748
                            $this->values['reportFile'] = $dir.'/'.basename($this->values['reportFile']);
749
                        }
750
                    }
751
                }//end if
752
753
                if (is_dir($this->values['reportFile']) === true) {
754
                    echo 'ERROR: The specified report file path "'.$this->values['reportFile'].'" is a directory'.PHP_EOL.PHP_EOL;
755
                    $this->printUsage();
756
                    exit(2);
757
                }
758
            } else if (substr($arg, 0, 13) === 'report-width=') {
759
                $this->values['reportWidth'] = $this->_validateReportWidth(substr($arg, 13));
760
            } else if (substr($arg, 0, 7) === 'report='
761
                || substr($arg, 0, 7) === 'report-'
762
            ) {
763
                if ($arg[6] === '-') {
764
                    // This is a report with file output.
765
                    $split = strpos($arg, '=');
766
                    if ($split === false) {
767
                        $report = substr($arg, 7);
768
                        $output = null;
769
                    } else {
770
                        $report = substr($arg, 7, ($split - 7));
771
                        $output = substr($arg, ($split + 1));
772
                        if ($output === false) {
773
                            $output = null;
774
                        } else {
775
                            $dir = dirname($output);
776
                            if ($dir === '.') {
777
                                // Passed report file is a filename in the current directory.
778
                                $output = getcwd().'/'.basename($output);
779
                            } else {
780
                                if ($dir{0} === '/') {
781
                                    // An absolute path.
782
                                    $dir = PHP_CodeSniffer::realpath($dir);
783
                                } else {
784
                                    $dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
785
                                }
786
787
                                if ($dir !== false) {
788
                                    // Report file path is relative.
789
                                    $output = $dir.'/'.basename($output);
790
                                }
791
                            }
792
                        }//end if
793
                    }//end if
794
                } else {
795
                    // This is a single report.
796
                    $report = substr($arg, 7);
797
                    $output = null;
798
                }//end if
799
800
                $this->values['reports'][$report] = $output;
801
            } else if (substr($arg, 0, 9) === 'standard=') {
802
                $standards = trim(substr($arg, 9));
803
                if ($standards !== '') {
804
                    $this->values['standard'] = explode(',', $standards);
805
                }
806
            } else if (substr($arg, 0, 11) === 'extensions=') {
807
                if (isset($this->values['extensions']) === false) {
808
                    $this->values['extensions'] = array();
809
                }
810
811
                $this->values['extensions'] = array_merge($this->values['extensions'], explode(',', substr($arg, 11)));
812
            } else if (substr($arg, 0, 9) === 'severity=') {
813
                $this->values['errorSeverity']   = (int) substr($arg, 9);
814
                $this->values['warningSeverity'] = $this->values['errorSeverity'];
815
            } else if (substr($arg, 0, 15) === 'error-severity=') {
816
                $this->values['errorSeverity'] = (int) substr($arg, 15);
817
            } else if (substr($arg, 0, 17) === 'warning-severity=') {
818
                $this->values['warningSeverity'] = (int) substr($arg, 17);
819
            } else if (substr($arg, 0, 7) === 'ignore=') {
820
                // Split the ignore string on commas, unless the comma is escaped
821
                // using 1 or 3 slashes (\, or \\\,).
822
                $ignored = preg_split(
823
                    '/(?<=(?<!\\\\)\\\\\\\\),|(?<!\\\\),/',
824
                    substr($arg, 7)
825
                );
826
                foreach ($ignored as $pattern) {
827
                    $pattern = trim($pattern);
828
                    if ($pattern === '') {
829
                        continue;
830
                    }
831
832
                    $this->values['ignored'][$pattern] = 'absolute';
833
                }
834
            } else if (substr($arg, 0, 10) === 'generator=') {
835
                $this->values['generator'] = substr($arg, 10);
836
            } else if (substr($arg, 0, 9) === 'encoding=') {
837
                $this->values['encoding'] = strtolower(substr($arg, 9));
838
            } else if (substr($arg, 0, 10) === 'tab-width=') {
839
                $this->values['tabWidth'] = (int) substr($arg, 10);
840
            } else {
841
                if ($this->dieOnUnknownArg === false) {
842
                    $eqPos = strpos($arg, '=');
843
                    if ($eqPos === false) {
844
                        $this->values[$arg] = $arg;
845
                    } else {
846
                        $value = substr($arg, ($eqPos + 1));
847
                        $arg   = substr($arg, 0, $eqPos);
848
                        $this->values[$arg] = $value;
849
                    }
850
                } else {
851
                    $this->processUnknownArgument('--'.$arg, $pos);
852
                }
853
            }//end if
854
855
            break;
856
        }//end switch
857
858
    }//end processLongArgument()
859
860
861
    /**
862
     * Processes an unknown command line argument.
863
     *
864
     * Assumes all unknown arguments are files and folders to check.
865
     *
866
     * @param string $arg The command line argument.
867
     * @param int    $pos The position of the argument on the command line.
868
     *
869
     * @return void
870
     */
871
    public function processUnknownArgument($arg, $pos)
872
    {
873
        // We don't know about any additional switches; just files.
874
        if ($arg{0} === '-') {
875
            if ($this->dieOnUnknownArg === false) {
876
                return;
877
            }
878
879
            echo 'ERROR: option "'.$arg.'" not known.'.PHP_EOL.PHP_EOL;
880
            $this->printUsage();
881
            exit(2);
882
        }
883
884
        $file = PHP_CodeSniffer::realpath($arg);
885
        if (file_exists($file) === false) {
886
            if ($this->dieOnUnknownArg === false) {
887
                return;
888
            }
889
890
            echo 'ERROR: The file "'.$arg.'" does not exist.'.PHP_EOL.PHP_EOL;
891
            $this->printUsage();
892
            exit(2);
893
        } else {
894
            $this->values['files'][] = $file;
895
        }
896
897
    }//end processUnknownArgument()
898
899
900
    /**
901
     * Runs PHP_CodeSniffer over files and directories.
902
     *
903
     * @param array $values An array of values determined from CLI args.
904
     *
905
     * @return int The number of error and warning messages shown.
906
     * @see    getCommandLineValues()
907
     */
908
    public function process($values=array())
909
    {
910
        if (empty($values) === true) {
911
            $values = $this->getCommandLineValues();
912
        } else {
913
            $values       = array_merge($this->getDefaults(), $values);
914
            $this->values = $values;
915
        }
916
917
        if ($values['generator'] !== '') {
918
            $phpcs = new PHP_CodeSniffer($values['verbosity']);
919
            if ($values['standard'] === null) {
920
                $values['standard'] = $this->validateStandard(null);
921
            }
922
923
            foreach ($values['standard'] as $standard) {
924
                $phpcs->generateDocs(
925
                    $standard,
926
                    $values['sniffs'],
927
                    $values['generator']
928
                );
929
            }
930
931
            exit(0);
932
        }
933
934
        // If no standard is supplied, get the default.
935
        $values['standard'] = $this->validateStandard($values['standard']);
936
        foreach ($values['standard'] as $standard) {
937
            if (PHP_CodeSniffer::isInstalledStandard($standard) === false) {
938
                // They didn't select a valid coding standard, so help them
939
                // out by letting them know which standards are installed.
940
                echo 'ERROR: the "'.$standard.'" coding standard is not installed. ';
941
                $this->printInstalledStandards();
942
                exit(2);
943
            }
944
        }
945
946
        if ($values['explain'] === true) {
947
            foreach ($values['standard'] as $standard) {
948
                $this->explainStandard($standard);
949
            }
950
951
            exit(0);
952
        }
953
954
        $phpcs = new PHP_CodeSniffer($values['verbosity'], null, null, null);
955
        $phpcs->setCli($this);
956
        $phpcs->initStandard($values['standard'], $values['sniffs'], $values['exclude']);
957
        $values = $this->values;
958
959
        $phpcs->setTabWidth($values['tabWidth']);
960
        $phpcs->setEncoding($values['encoding']);
961
        $phpcs->setInteractive($values['interactive']);
962
963
        // Set file extensions if they were specified. Otherwise,
964
        // let PHP_CodeSniffer decide on the defaults.
965
        if (empty($values['extensions']) === false) {
966
            $phpcs->setAllowedFileExtensions($values['extensions']);
967
        }
968
969
        // Set ignore patterns if they were specified.
970
        if (empty($values['ignored']) === false) {
971
            $ignorePatterns = array_merge($phpcs->getIgnorePatterns(), $values['ignored']);
972
            $phpcs->setIgnorePatterns($ignorePatterns);
973
        }
974
975
        // Set some convenience member vars.
976
        if ($values['errorSeverity'] === null) {
977
            $this->errorSeverity = PHPCS_DEFAULT_ERROR_SEV;
978
        } else {
979
            $this->errorSeverity = $values['errorSeverity'];
980
        }
981
982
        if ($values['warningSeverity'] === null) {
983
            $this->warningSeverity = PHPCS_DEFAULT_WARN_SEV;
984
        } else {
985
            $this->warningSeverity = $values['warningSeverity'];
986
        }
987
988
        if (empty($values['reports']) === true) {
989
            $values['reports']['full'] = $values['reportFile'];
990
            $this->values['reports']   = $values['reports'];
991
        }
992
993
        // Include bootstrap files.
994
        foreach ($values['bootstrap'] as $bootstrap) {
995
            include $bootstrap;
996
        }
997
998
        $phpcs->processFiles($values['files'], $values['local']);
999
1000
        if (empty($values['files']) === true || $values['stdin'] !== null) {
1001
            $fileContents = $values['stdin'];
1002
            if ($fileContents === null) {
1003
                // Check if they are passing in the file contents.
1004
                $handle = fopen('php://stdin', 'r');
1005
                stream_set_blocking($handle, true);
1006
                $fileContents = stream_get_contents($handle);
1007
                fclose($handle);
1008
            }
1009
1010
            if ($fileContents === '') {
1011
                // No files and no content passed in.
1012
                echo 'ERROR: You must supply at least one file or directory to process.'.PHP_EOL.PHP_EOL;
1013
                $this->printUsage();
1014
                exit(2);
1015
            } else {
1016
                $phpcs->processFile('STDIN', $fileContents);
1017
            }
1018
        }
1019
1020
        // Interactive runs don't require a final report and it doesn't really
1021
        // matter what the retun value is because we know it isn't being read
1022
        // by a script.
1023
        if ($values['interactive'] === true) {
1024
            return 0;
1025
        }
1026
1027
        return $this->printErrorReport(
1028
            $phpcs,
1029
            $values['reports'],
1030
            $values['showSources'],
1031
            $values['reportFile'],
1032
            $values['reportWidth']
1033
        );
1034
1035
    }//end process()
1036
1037
1038
    /**
1039
     * Prints the error report for the run.
1040
     *
1041
     * Note that this function may actually print multiple reports
1042
     * as the user may have specified a number of output formats.
1043
     *
1044
     * @param PHP_CodeSniffer $phpcs       The PHP_CodeSniffer object containing
1045
     *                                     the errors.
1046
     * @param array           $reports     A list of reports to print.
1047
     * @param bool            $showSources TRUE if report should show error sources
1048
     *                                     (not used by all reports).
1049
     * @param string          $reportFile  A default file to log report output to.
1050
     * @param int             $reportWidth How wide the screen reports should be.
1051
     *
1052
     * @return int The number of error and warning messages shown.
1053
     */
1054
    public function printErrorReport(
1055
        PHP_CodeSniffer $phpcs,
1056
        $reports,
1057
        $showSources,
1058
        $reportFile,
1059
        $reportWidth
1060
    ) {
1061
        if (empty($reports) === true) {
1062
            $reports['full'] = $reportFile;
1063
        }
1064
1065
        $errors   = 0;
1066
        $warnings = 0;
1067
        $toScreen = false;
1068
1069
        foreach ($reports as $report => $output) {
1070
            if ($output === null) {
1071
                $output = $reportFile;
1072
            }
1073
1074
            if ($reportFile === null) {
1075
                $toScreen = true;
1076
            }
1077
1078
            // We don't add errors here because the number of
1079
            // errors reported by each report type will always be the
1080
            // same, so we really just need 1 number.
1081
            $result = $phpcs->reporting->printReport(
1082
                $report,
1083
                $showSources,
1084
                $this->values,
1085
                $output,
1086
                $reportWidth
1087
            );
1088
1089
            $errors   = $result['errors'];
1090
            $warnings = $result['warnings'];
1091
        }//end foreach
1092
1093
        // Only print timer output if no reports were
1094
        // printed to the screen so we don't put additional output
1095
        // in something like an XML report. If we are printing to screen,
1096
        // the report types would have already worked out who should
1097
        // print the timer info.
1098
        if (PHP_CODESNIFFER_INTERACTIVE === false
1099
            && ($toScreen === false
1100
            || (($errors + $warnings) === 0 && $this->values['showProgress'] === true))
1101
        ) {
1102
            PHP_CodeSniffer_Reporting::printRunTime();
1103
        }
1104
1105
        // They should all return the same value, so it
1106
        // doesn't matter which return value we end up using.
1107
        $ignoreWarnings = PHP_CodeSniffer::getConfigData('ignore_warnings_on_exit');
1108
        $ignoreErrors   = PHP_CodeSniffer::getConfigData('ignore_errors_on_exit');
1109
1110
        $return = ($errors + $warnings);
1111
        if ($ignoreErrors !== null) {
1112
            $ignoreErrors = (bool) $ignoreErrors;
1113
            if ($ignoreErrors === true) {
1114
                $return -= $errors;
1115
            }
1116
        }
1117
1118
        if ($ignoreWarnings !== null) {
1119
            $ignoreWarnings = (bool) $ignoreWarnings;
1120
            if ($ignoreWarnings === true) {
1121
                $return -= $warnings;
1122
            }
1123
        }
1124
1125
        return $return;
1126
1127
    }//end printErrorReport()
1128
1129
1130
    /**
1131
     * Convert the passed standards into valid standards.
1132
     *
1133
     * Checks things like default values and case.
1134
     *
1135
     * @param array $standards The standards to validate.
1136
     *
1137
     * @return array
1138
     */
1139
    public function validateStandard($standards)
1140
    {
1141
        if ($standards === null) {
1142
            // They did not supply a standard to use.
1143
            // Look for a default ruleset in the current directory or higher.
1144
            $currentDir = getcwd();
1145
1146
            do {
1147
                $default = $currentDir.DIRECTORY_SEPARATOR.'phpcs.xml';
1148
                if (is_file($default) === true) {
1149
                    return array($default);
1150
                }
1151
1152
                $default = $currentDir.DIRECTORY_SEPARATOR.'phpcs.xml.dist';
1153
                if (is_file($default) === true) {
1154
                    return array($default);
1155
                }
1156
1157
                $lastDir    = $currentDir;
1158
                $currentDir = dirname($currentDir);
1159
            } while ($currentDir !== '.' && $currentDir !== $lastDir);
1160
1161
            // Try to get the default from the config system.
1162
            $standard = PHP_CodeSniffer::getConfigData('default_standard');
1163
            if ($standard === null) {
1164
                // Product default standard.
1165
                $standard = 'PEAR';
1166
            }
1167
1168
            return explode(',', $standard);
1169
        }//end if
1170
1171
        $cleaned   = array();
1172
        $standards = (array) $standards;
1173
1174
        // Check if the standard name is valid, or if the case is invalid.
1175
        $installedStandards = PHP_CodeSniffer::getInstalledStandards();
1176
        foreach ($standards as $standard) {
1177
            foreach ($installedStandards as $validStandard) {
1178
                if (strtolower($standard) === strtolower($validStandard)) {
1179
                    $standard = $validStandard;
1180
                    break;
1181
                }
1182
            }
1183
1184
            $cleaned[] = $standard;
1185
        }
1186
1187
        return $cleaned;
1188
1189
    }//end validateStandard()
1190
1191
1192
    /**
1193
     * Prints a report showing the sniffs contained in a standard.
1194
     *
1195
     * @param string $standard The standard to validate.
1196
     *
1197
     * @return void
1198
     */
1199
    public function explainStandard($standard)
1200
    {
1201
        $phpcs = new PHP_CodeSniffer();
1202
        $phpcs->process(array(), $standard);
1203
        $sniffs = $phpcs->getSniffs();
1204
        $sniffs = array_keys($sniffs);
1205
        sort($sniffs);
1206
1207
        ob_start();
1208
1209
        $lastStandard = '';
1210
        $lastCount    = '';
1211
        $sniffCount   = count($sniffs);
1212
        $sniffs[]     = '___';
1213
1214
        echo PHP_EOL."The $standard standard contains $sniffCount sniffs".PHP_EOL;
1215
1216
        ob_start();
1217
1218
        foreach ($sniffs as $sniff) {
1219
            $parts = explode('_', str_replace('\\', '_', $sniff));
1220
            if ($lastStandard === '') {
1221
                $lastStandard = $parts[0];
1222
            }
1223
1224
            if ($parts[0] !== $lastStandard) {
1225
                $sniffList = ob_get_contents();
1226
                ob_end_clean();
1227
1228
                echo PHP_EOL.$lastStandard.' ('.$lastCount.' sniffs)'.PHP_EOL;
1229
                echo str_repeat('-', (strlen($lastStandard.$lastCount) + 10));
1230
                echo PHP_EOL;
1231
                echo $sniffList;
1232
1233
                $lastStandard = $parts[0];
1234
                $lastCount    = 0;
1235
1236
                ob_start();
1237
            }
1238
1239
            echo '  '.$parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5).PHP_EOL;
1240
            $lastCount++;
1241
        }//end foreach
1242
1243
        ob_end_clean();
1244
1245
    }//end explainStandard()
1246
1247
1248
    /**
1249
     * Prints out the gathered config data.
1250
     *
1251
     * @param array $data The config data to print.
1252
     *
1253
     * @return void
1254
     */
1255
    public function printConfigData($data)
1256
    {
1257
        $max  = 0;
1258
        $keys = array_keys($data);
1259
        foreach ($keys as $key) {
1260
            $len = strlen($key);
1261
            if (strlen($key) > $max) {
1262
                $max = $len;
1263
            }
1264
        }
1265
1266
        if ($max === 0) {
1267
            return;
1268
        }
1269
1270
        $max += 2;
1271
        ksort($data);
1272
        foreach ($data as $name => $value) {
1273
            echo str_pad($name.': ', $max).$value.PHP_EOL;
1274
        }
1275
1276
    }//end printConfigData()
1277
1278
1279
    /**
1280
     * Prints out the usage information for this script.
1281
     *
1282
     * @return void
1283
     */
1284
    public function printUsage()
1285
    {
1286
        if (PHP_CODESNIFFER_CBF === true) {
1287
            $this->printPHPCBFUsage();
1288
        } else {
1289
            $this->printPHPCSUsage();
1290
        }
1291
1292
    }//end printUsage()
1293
1294
1295
    /**
1296
     * Prints out the usage information for PHPCS.
1297
     *
1298
     * @return void
1299
     */
1300
    public function printPHPCSUsage()
1301
    {
1302
        echo 'Usage: phpcs [-nwlsaepqvi] [-d key[=value]] [--colors] [--no-colors] [--stdin-path=<stdinPath>]'.PHP_EOL;
1303
        echo '    [--report=<report>] [--report-file=<reportFile>] [--report-<report>=<reportFile>] ...'.PHP_EOL;
1304
        echo '    [--report-width=<reportWidth>] [--generator=<generator>] [--tab-width=<tabWidth>]'.PHP_EOL;
1305
        echo '    [--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]'.PHP_EOL;
1306
        echo '    [--runtime-set key value] [--config-set key value] [--config-delete key] [--config-show]'.PHP_EOL;
1307
        echo '    [--standard=<standard>] [--sniffs=<sniffs>] [--exclude=<sniffs>] [--encoding=<encoding>]'.PHP_EOL;
1308
        echo '    [--extensions=<extensions>] [--ignore=<patterns>] [--bootstrap=<bootstrap>]'.PHP_EOL;
1309
        echo '    [--file-list=<fileList>] <file> ...'.PHP_EOL;
1310
        echo '                      Set runtime value (see --config-set) '.PHP_EOL;
1311
        echo '        -n            Do not print warnings (shortcut for --warning-severity=0)'.PHP_EOL;
1312
        echo '        -w            Print both warnings and errors (this is the default)'.PHP_EOL;
1313
        echo '        -l            Local directory only, no recursion'.PHP_EOL;
1314
        echo '        -s            Show sniff codes in all reports'.PHP_EOL;
1315
        echo '        -a            Run interactively'.PHP_EOL;
1316
        echo '        -e            Explain a standard by showing the sniffs it includes'.PHP_EOL;
1317
        echo '        -p            Show progress of the run'.PHP_EOL;
1318
        echo '        -q            Quiet mode; disables progress and verbose output'.PHP_EOL;
1319
        echo '        -v[v][v]      Print verbose output'.PHP_EOL;
1320
        echo '        -i            Show a list of installed coding standards'.PHP_EOL;
1321
        echo '        -d            Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
1322
        echo '        --help        Print this help message'.PHP_EOL;
1323
        echo '        --version     Print version information'.PHP_EOL;
1324
        echo '        --colors      Use colors in output'.PHP_EOL;
1325
        echo '        --no-colors   Do not use colors in output (this is the default)'.PHP_EOL;
1326
        echo '        <file>        One or more files and/or directories to check'.PHP_EOL;
1327
        echo '        <fileList>    A file containing a list of files and/or directories to check (one per line)'.PHP_EOL;
1328
        echo '        <stdinPath>   If processing STDIN, the file path that STDIN will be processed as '.PHP_EOL;
1329
        echo '        <bootstrap>   A comma separated list of files to run before processing starts'.PHP_EOL;
1330
        echo '        <encoding>    The encoding of the files being checked (default is iso-8859-1)'.PHP_EOL;
1331
        echo '        <extensions>  A comma separated list of file extensions to check'.PHP_EOL;
1332
        echo '                      (extension filtering only valid when checking a directory)'.PHP_EOL;
1333
        echo '                      The type of the file can be specified using: ext/type'.PHP_EOL;
1334
        echo '                      e.g., module/php,es/js'.PHP_EOL;
1335
        echo '        <generator>   Uses either the "HTML", "Markdown" or "Text" generator'.PHP_EOL;
1336
        echo '                      (forces documentation generation instead of checking)'.PHP_EOL;
1337
        echo '        <patterns>    A comma separated list of patterns to ignore files and directories'.PHP_EOL;
1338
        echo '        <report>      Print either the "full", "xml", "checkstyle", "csv"'.PHP_EOL;
1339
        echo '                      "json", "emacs", "source", "summary", "diff", "junit"'.PHP_EOL;
1340
        echo '                      "svnblame", "gitblame", "hgblame" or "notifysend" report'.PHP_EOL;
1341
        echo '                      (the "full" report is printed by default)'.PHP_EOL;
1342
        echo '        <reportFile>  Write the report to the specified file path'.PHP_EOL;
1343
        echo '        <reportWidth> How many columns wide screen reports should be printed'.PHP_EOL;
1344
        echo '                      or set to "auto" to use current screen width, where supported'.PHP_EOL;
1345
        echo '        <sniffs>      A comma separated list of sniff codes to include or exclude during checking'.PHP_EOL;
1346
        echo '                      (all sniffs must be part of the specified standard)'.PHP_EOL;
1347
        echo '        <severity>    The minimum severity required to display an error or warning'.PHP_EOL;
1348
        echo '        <standard>    The name or path of the coding standard to use'.PHP_EOL;
1349
        echo '        <tabWidth>    The number of spaces each tab represents'.PHP_EOL;
1350
1351
    }//end printPHPCSUsage()
1352
1353
1354
    /**
1355
     * Prints out the usage information for PHPCBF.
1356
     *
1357
     * @return void
1358
     */
1359
    public function printPHPCBFUsage()
1360
    {
1361
        echo 'Usage: phpcbf [-nwli] [-d key[=value]] [--stdin-path=<stdinPath>]'.PHP_EOL;
1362
        echo '    [--standard=<standard>] [--sniffs=<sniffs>] [--exclude=<sniffs>] [--suffix=<suffix>]'.PHP_EOL;
1363
        echo '    [--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]'.PHP_EOL;
1364
        echo '    [--tab-width=<tabWidth>] [--encoding=<encoding>]'.PHP_EOL;
1365
        echo '    [--extensions=<extensions>] [--ignore=<patterns>] [--bootstrap=<bootstrap>]'.PHP_EOL;
1366
        echo '    [--file-list=<fileList>] <file> ...'.PHP_EOL;
1367
        echo '        -n            Do not fix warnings (shortcut for --warning-severity=0)'.PHP_EOL;
1368
        echo '        -w            Fix both warnings and errors (on by default)'.PHP_EOL;
1369
        echo '        -l            Local directory only, no recursion'.PHP_EOL;
1370
        echo '        -i            Show a list of installed coding standards'.PHP_EOL;
1371
        echo '        -d            Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
1372
        echo '        --help        Print this help message'.PHP_EOL;
1373
        echo '        --version     Print version information'.PHP_EOL;
1374
        echo '        --no-patch    Do not make use of the "diff" or "patch" programs'.PHP_EOL;
1375
        echo '        <file>        One or more files and/or directories to fix'.PHP_EOL;
1376
        echo '        <fileList>    A file containing a list of files and/or directories to fix (one per line)'.PHP_EOL;
1377
        echo '        <stdinPath>   If processing STDIN, the file path that STDIN will be processed as '.PHP_EOL;
1378
        echo '        <bootstrap>   A comma separated list of files to run before processing starts'.PHP_EOL;
1379
        echo '        <encoding>    The encoding of the files being fixed (default is iso-8859-1)'.PHP_EOL;
1380
        echo '        <extensions>  A comma separated list of file extensions to fix'.PHP_EOL;
1381
        echo '                      (extension filtering only valid when checking a directory)'.PHP_EOL;
1382
        echo '                      The type of the file can be specified using: ext/type'.PHP_EOL;
1383
        echo '                      e.g., module/php,es/js'.PHP_EOL;
1384
        echo '        <patterns>    A comma separated list of patterns to ignore files and directories'.PHP_EOL;
1385
        echo '        <sniffs>      A comma separated list of sniff codes to include or exclude during fixing'.PHP_EOL;
1386
        echo '                      (all sniffs must be part of the specified standard)'.PHP_EOL;
1387
        echo '        <severity>    The minimum severity required to fix an error or warning'.PHP_EOL;
1388
        echo '        <standard>    The name or path of the coding standard to use'.PHP_EOL;
1389
        echo '        <suffix>      Write modified files to a filename using this suffix'.PHP_EOL;
1390
        echo '                      ("diff" and "patch" are not used in this mode)'.PHP_EOL;
1391
        echo '        <tabWidth>    The number of spaces each tab represents'.PHP_EOL;
1392
1393
    }//end printPHPCBFUsage()
1394
1395
1396
    /**
1397
     * Prints out a list of installed coding standards.
1398
     *
1399
     * @return void
1400
     */
1401
    public function printInstalledStandards()
1402
    {
1403
        $installedStandards = PHP_CodeSniffer::getInstalledStandards();
1404
        $numStandards       = count($installedStandards);
1405
1406
        if ($numStandards === 0) {
1407
            echo 'No coding standards are installed.'.PHP_EOL;
1408
        } else {
1409
            $lastStandard = array_pop($installedStandards);
1410
            if ($numStandards === 1) {
1411
                echo "The only coding standard installed is $lastStandard".PHP_EOL;
1412
            } else {
1413
                $standardList  = implode(', ', $installedStandards);
1414
                $standardList .= ' and '.$lastStandard;
1415
                echo 'The installed coding standards are '.$standardList.PHP_EOL;
1416
            }
1417
        }
1418
1419
    }//end printInstalledStandards()
1420
1421
1422
    /**
1423
     * Set report width based on terminal width.
1424
     *
1425
     * @param int $width The width of the report. If "auto" then will
1426
     *                   be replaced by the terminal width.
1427
     *
1428
     * @return int
1429
     */
1430
    private function _validateReportWidth($width)
1431
    {
1432
        if ($width === 'auto'
1433
            && preg_match('|\d+ (\d+)|', shell_exec('stty size 2>&1'), $matches) === 1
1434
        ) {
1435
            return (int) $matches[1];
1436
        }
1437
1438
        return (int) $width;
1439
1440
    }//end _validateReportWidth()
1441
1442
1443
}//end class
1444