Skip to content

Commit 88d8f47

Browse files
authored
Merge pull request #70 from jamessampford/master
Adds PHP 8.1 and Junit Support
2 parents 37cdf74 + 87549db commit 88d8f47

File tree

6 files changed

+297
-28
lines changed

6 files changed

+297
-28
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ Options:
7777
-s, --max-size[=MAX-SIZE] Sets max size of php file. If file is larger, it will be skipped. [default: "1mb"]
7878
--file-extensions[=FILE-EXTENSIONS] Sets file extensions to be parsed. [default: "php, php5, phtml"]
7979
--skip-checks[=SKIP-CHECKS] Skip all checks containing any of the given values. Pass a comma-separated list for multiple values.
80-
--output-json[=OUTPUT-JSON] Path to store json-file with analyze results. If '-' passed, json will be printed on stdout.
80+
--output[=OUTPUT] The output type required. Options: stdout, json, junit. Defaults to stdout.
81+
--output-file[=OUTPUT-FILE] File path to store results where output is not stdout.
8182
-h, --help Display help for the given command. When no command is given display help for the scan command
8283
-q, --quiet Do not output any message
8384
-V, --version Display this application version
@@ -91,7 +92,7 @@ Options:
9192
- By providing `--exclude` option you can exclude specific folders or files from analyze. For example, `--exclude vendor` will prevent checking third-party libraries.
9293
- By providing `--skip-checks` option you can exclude specific checks from analyze.
9394
- If your files has unusual extension, you can specify all exts by `--file-extensions` option. By default, it uses `php`, `phtml` and `php5`.
94-
- If you need to generate machine-readable analyze result, use `--output-json` option to specify path to store json or `--output-json=-` to print json to stdout.
95+
- If you need to generate machine-readable analyze result, use the `--output-file` option to specify path to store the output file as specified on `--output` (json or junit).
9596

9697
### Example of usage
9798
```
@@ -122,7 +123,10 @@ Folder /media/wapmorgan/Локальный диск/Документы/PhpDeprec
122123
```
123124

124125
## Json report format
125-
Also, you can store analyze result in json format for automatic check. Pass `--output-json=FILENAME` to write result to **FILENAME** file or `--output-json=-` to output to *stdout*.
126+
Also, you can store analyze result in json format for automatic check. Pass `--output-file=FILENAME` to write result to **FILENAME** file or do not set to output to *stdout*.
127+
128+
## Junit report format
129+
Also, you can store analyze result in junit format for automatic check. Pass `--output-file=FILENAME` to write result to **FILENAME** file or do not set to output to *stdout*.
126130

127131
**Format of json** - dictionary with items:
128132
- InfoMessage[] **info_messages** - list of information messages about analyzing process.
@@ -139,6 +143,7 @@ Items description:
139143
- string **file** - relative path to file in which issue found (*like src/ProblemClass.php*)
140144
- string **path** - absolute path to file in which issue found (*like /var/www/html/project/src/ProblemClass.php*)
141145
- int **line** - line in file in which issue found
146+
- int **column** - column in line in which issue found
142147
- string **category** - issue category - any of (changed | removed | violation)
143148
- string **type** - concrete issue type (*like "constant" or "identifier"*)
144149
- string **checker** - concrete issue object which may cause problem (*like `magic_quotes_runtime` or `preg_replace() (@preg_replace_e_modifier)`*)

data/8.1.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
return [
3+
/**
4+
* @see https://github.com/php/php-src/blob/PHP-8.1.6/UPGRADING
5+
*/
6+
'functions' => [
7+
// @see CORE
8+
'__serialize' =>'deprecate, if you order php support both implement https://wiki.php.net/rfc/phase_out_serializable',
9+
'__unserialize' => 'deprecate, if you order php support both implement https://wiki.php.net/rfc/phase_out_serializable',
10+
11+
// @seeDate
12+
'date_sunrise' => 'deprecate it will remove in php 9.0',
13+
'date_sunset' => 'deprecate it will remove in php 9.0',
14+
'strftime' => 'date/DateTime::format() or IntlDateFormatter::format()',
15+
'gmstrftime' => 'date/DateTime::format() or IntlDateFormatter::format()',
16+
17+
// @see Hash
18+
'mhash' => 'Use the hash_*() APIs instead',
19+
'mhash_keygen_s2k' => 'Use the hash_*() APIs instead',
20+
'mhash_count' => 'Use the hash_*() APIs instead',
21+
'mhash_get_block_size' => 'Use the hash_*() APIs instead',
22+
23+
// @see Intl
24+
'roll' => 'Calling IntlCalendar::roll() with bool argument is deprecated. Pass 1 and -1 instead of true and false respectively.',
25+
26+
// @see Standard
27+
'key' => 'use with objects is deprecated',
28+
'current' => 'use with objects is deprecated',
29+
'next' => 'use with objects is deprecated',
30+
'prev' => 'use with objects is deprecated',
31+
'reset' => 'use with objects is deprecated',
32+
'end' => 'use with objects is deprecated',
33+
'strptime' => 'Deprecated. Use date_parse_from_format() or IntlDateFormatter::parse',
34+
35+
// @see MySQLi
36+
'MYSQLI_REFRESH_REPLICA' => 'Use MYSQLI_REFRESH_SLAVE. The old constant is still available for backwards-compatibility reasons,
37+
but may be deprecated/removed in the future.'
38+
],
39+
'constants' => [
40+
/**
41+
* @see https://github.com/php/php-src/blob/PHP-8.1.6/UPGRADING
42+
*/
43+
'MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH',
44+
'MYSQLI_STORE_RESULT_COPY_DATA',
45+
'FILTER_SANITIZE_STRING' => 'Deprecated',
46+
'FILTER_SANITIZE_STRIPPED' => 'Deprecated',
47+
'NIL' => 'Deprecated, Use 0 instead',
48+
'FILE_BINARY' => 'deprecated. They already had no effect previously.',
49+
'FILE_TEXT' => 'deprecated. They already had no effect previously.',
50+
],
51+
'ini_settings' => [
52+
'mysqlnd.fetch_data_copy',
53+
'filter.default' => 'Deprecated',
54+
'oci8.old_oci_close_semantics' => 'Deprecated',
55+
'auto_detect_line_endings' => 'Deprecated',
56+
'log_errors_max_len', //removed
57+
],
58+
'identifiers' => [
59+
'enum'
60+
]
61+
];

src/PhpCodeFixer.php

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class PhpCodeFixer {
1111
/**
1212
* @var array
1313
*/
14-
static public $availableTargets = ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0'];
14+
static public $availableTargets = ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'];
1515

1616
/**
1717
* @var array Extensions of file to process.
@@ -53,6 +53,11 @@ class PhpCodeFixer {
5353
*/
5454
protected $fileExtensions;
5555

56+
/**
57+
* @var array
58+
*/
59+
public $scannedFiles = [];
60+
5661
/**
5762
* PhpCodeFixer constructor.
5863
*/
@@ -190,6 +195,8 @@ protected function checkDirInternal($dir, Report $report) {
190195
* @return Report|bool
191196
*/
192197
public function checkFile($file, Report $report = null) {
198+
$this->scannedFiles[] = realpath($file);
199+
193200
if ($report === null) {
194201
$report = new Report('File ' . basename($file), dirname(realpath($file)));
195202
$previous_error_handler = set_error_handler([$this, 'handleError']);
@@ -203,6 +210,18 @@ public function checkFile($file, Report $report = null) {
203210
try {
204211
$tokens = token_get_all(file_get_contents($file));
205212

213+
$line = 1;
214+
$col = 1;
215+
foreach ($tokens as $k => $token) {
216+
if (is_array($token)) {
217+
list ($token, $text) = $token;
218+
$tokens[$k][3] = $col;
219+
} else if (is_string($token)) {
220+
$text = $token;
221+
}
222+
$this->updateLineColumnPositions($text, $line, $col);
223+
}
224+
206225
// cut off heredoc, comments
207226
while (in_array_column($tokens, T_START_HEREDOC, 0)) {
208227
$start = array_search_column($tokens, T_START_HEREDOC, 0);
@@ -371,6 +390,7 @@ protected function analyzeMethodsNaming($currentFile, Report $report, array &$to
371390
$method_name = $tokens[$i + 2][1];
372391
$methods[$method_name] = [
373392
'line' => $tokens[$i][2],
393+
'column' => $tokens[$i][3],
374394
'attributes' => $method_attributes
375395
];
376396
}
@@ -384,7 +404,7 @@ protected function analyzeMethodsNaming($currentFile, Report $report, array &$to
384404
$result = $checker($class_name, $method_name, $method_data['attributes'], $methods, $namespace);
385405
if ($result !== false) {
386406
$report->addIssue($methods_naming_checker[1], ReportIssue::CHANGED, ReportIssue::DEPRECATED_FEATURE,
387-
$method_name . ':' . $class_name . ' (' . $methods_naming_checker[0] . ')', $result, $currentFile, $method_data['line']);
407+
$method_name . ':' . $class_name . ' (' . $methods_naming_checker[0] . ')', $result, $currentFile, $method_data['line'], $method_data['column']);
388408
}
389409
}
390410
}
@@ -429,7 +449,7 @@ protected function analyzeIdentifiers($currentFile, Report $report, array &$toke
429449
if (isset($identifiers[$used_identifier_word])) {
430450
$identifier = $identifiers[$used_identifier_word];
431451
$report->addIssue($identifier[1], ReportIssue::VIOLATION, ReportIssue::RESERVED_IDENTIFIER,
432-
$used_identifier[1], null, $currentFile, $used_identifier[2]);
452+
$used_identifier[1], null, $currentFile, $used_identifier[2], $used_identifier[3]);
433453
}
434454
}
435455
}
@@ -451,7 +471,7 @@ protected function analyzeVariables($currentFile, Report $report, array $tokens)
451471
if (isset($deprecated_varibales[$used_variable[1]])) {
452472
$variable = $deprecated_varibales[$used_variable[1]];
453473
$report->addIssue($variable[1], ReportIssue::REMOVED, ReportIssue::REMOVED_VARIABLE,
454-
$used_variable[1], ($variable[0] != $used_variable[1] ? $variable[0] : null), $currentFile, $used_variable[2]);
474+
$used_variable[1], ($variable[0] != $used_variable[1] ? $variable[0] : null), $currentFile, $used_variable[2], $used_variable[3]);
455475
}
456476
}
457477
}
@@ -545,7 +565,7 @@ protected function analyzeFunctionsUsage($currentFile, Report $report, array &$t
545565

546566
if ($result) {
547567
$report->addIssue($deprecated_functions_usage[$token[1]][1], ReportIssue::CHANGED, ReportIssue::DEPRECATED_FUNCTION_USAGE,
548-
$token[1] . '() (' . $deprecated_functions_usage[$token[1]][0] . ')', is_string($result) ? $result : null, $currentFile, $token[2]);
568+
$token[1] . '() (' . $deprecated_functions_usage[$token[1]][0] . ')', is_string($result) ? $result : null, $currentFile, $token[2], $token[3]);
549569
}
550570
}
551571

@@ -557,7 +577,7 @@ protected function analyzeFunctionsUsage($currentFile, Report $report, array &$t
557577
$functionTokens);
558578
if ($result) {
559579
$report->addIssue($global_function_usage_checker[1], ReportIssue::CHANGED, ReportIssue::DEPRECATED_FUNCTION_USAGE,
560-
$token[1] . '() (' . $global_function_usage_checker[0] . ')', is_string($result) ? $result : null, $currentFile, $token[2]);
580+
$token[1] . '() (' . $global_function_usage_checker[0] . ')', is_string($result) ? $result : null, $currentFile, $token[2], $token[3]);
561581
}
562582
}
563583
}
@@ -589,7 +609,7 @@ protected function analyzeIniSettings($currentFile, Report $report, array $token
589609
if (isset($deprecated_ini_settings[$ini_setting[1]])) {
590610
$deprecated_setting = $deprecated_ini_settings[$ini_setting[1]];
591611
$report->addIssue($deprecated_setting[1], ReportIssue::REMOVED, ReportIssue::REMOVED_INI_SETTING,
592-
$ini_setting[1], ($deprecated_setting[0] != $ini_setting[1] ? $deprecated_setting[0] : null), $currentFile, $ini_setting[2]);
612+
$ini_setting[1], ($deprecated_setting[0] != $ini_setting[1] ? $deprecated_setting[0] : null), $currentFile, $ini_setting[2], $ini_setting[3]);
593613
}
594614
}
595615
}
@@ -610,7 +630,7 @@ protected function analyzeConstants($currentFile, Report $report, array $tokens)
610630
if (isset($deprecated_constants[$used_constant[1]])) {
611631
$constant = $deprecated_constants[$used_constant[1]];
612632
$report->addIssue($constant[1], ReportIssue::REMOVED, ReportIssue::REMOVED_CONSTANT,
613-
$used_constant[1], ($constant[0] != $used_constant[1] ? $constant[0] : null), $currentFile, $used_constant[2]);
633+
$used_constant[1], ($constant[0] != $used_constant[1] ? $constant[0] : null), $currentFile, $used_constant[2], $used_constant[3]);
614634
}
615635
}
616636
}
@@ -648,7 +668,7 @@ protected function analyzeFunctions($currentFile, Report $report, array &$tokens
648668

649669
$function = $deprecated_functions[$used_function[1]];
650670
$report->addIssue($function[1], ReportIssue::REMOVED, ReportIssue::REMOVED_FUNCTION,
651-
$used_function[1], ($function[0] != $used_function[1] ? $function[0] : null), $currentFile, $used_function[2]);
671+
$used_function[1], ($function[0] != $used_function[1] ? $function[0] : null), $currentFile, $used_function[2], $used_function[3]);
652672
}
653673
}
654674
}
@@ -666,4 +686,26 @@ public function handleError($errorNumber, $errorMessage, $errorFile,
666686
{
667687
throw new ParsingException($errorMessage.' in file '.$errorFile.':'.$errorLine, $errorNumber);
668688
}
689+
690+
/**
691+
* @param $text
692+
* @param $line
693+
* @param $col
694+
*/
695+
696+
private function updateLineColumnPositions($text, &$line, &$col)
697+
{
698+
$numNewLines = substr_count($text, "\n");
699+
if (1 <= $numNewLines) {
700+
$line += $numNewLines;
701+
$col = 1;
702+
703+
$text = substr($text, strrpos($text, "\n") + 1);
704+
if ($text === false) {
705+
$text = '';
706+
}
707+
}
708+
$col += strlen($text);
709+
}
710+
669711
}

src/Report.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@ public function __construct($reportTitle, $removablePath = null)
4040
* @param string|null $replacement Possible replacement
4141
* @param string $file File in which issue present
4242
* @param integer $line Line of file
43+
* @param integer $column Column of file
4344
* @return void
4445
*/
45-
public function addIssue($version, $category, $type, $text, $replacement, $file, $line) {
46+
public function addIssue($version, $category, $type, $text, $replacement, $file, $line, $column) {
4647
if ($this->removablePath !== null && strncasecmp($file, $this->removablePath, strlen($this->removablePath)) === 0)
4748
$file = substr($file, strlen($this->removablePath));
4849
// $this->records[$version][] = [$type, $text, $replacement, $file, $line];
49-
$issue = new ReportIssue($version, $category, $type, $text, $file, $line);
50+
$issue = new ReportIssue($version, $category, $type, $text, realpath($this->removablePath.$file), $file, $line, $column);
5051
if (!empty($replacement))
5152
$issue->setReplacement($replacement);
5253
$this->records[$version][] = $issue;

src/ReportIssue.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,24 @@ class ReportIssue
1818
const REMOVED_VARIABLE = 'variable';
1919
public $version;
2020

21+
public $path;
2122
public $file;
2223
public $line;
24+
public $column;
2325

2426
public $category;
2527
public $type;
2628

2729
public $text;
2830
public $replacement;
2931

30-
public function __construct($version, $category, $type, $text, $file, $line)
32+
public function __construct($version, $category, $type, $text, $path, $file, $line, $column)
3133
{
3234
$this->version = $version;
35+
$this->path = $path;
3336
$this->file = $file;
3437
$this->line = $line;
38+
$this->column = $column;
3539
$this->type = $type;
3640
$this->category = $category;
3741
$this->text = $text;
@@ -42,4 +46,4 @@ public function setReplacement($replacement)
4246
$this->replacement = $replacement;
4347
return $this;
4448
}
45-
}
49+
}

0 commit comments

Comments
 (0)