├── CHANGELOG.md
├── LICENSE
├── README.md
├── composer.json
├── src
├── ArrayIterator.php
├── Checker.php
├── Exception
│ ├── Exception.php
│ ├── FileNotFound.php
│ ├── FileOpen.php
│ ├── InvalidArgument.php
│ └── NotExistsPath.php
├── FunctionArgument.php
├── FunctionConditions.php
├── Manager.php
├── Output.php
├── OutputColored.php
├── RecursiveDirectoryFilterIterator.php
├── Result.php
├── Settings.php
└── Writer
│ ├── Console.php
│ ├── File.php
│ ├── Multiple.php
│ └── Writer.php
├── var-dump-check
└── var-dump-check.php
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6 |
7 | ## [Unreleased]
8 |
9 | ### Internal
10 |
11 | - PHPUnit - Make the unit tests cross version compatible [#12](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/12) from [@jrfnl](https://github.com/jrfnl).
12 | - Travis: run the tests on PHP 8/nightly [#13](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/13) from [@jrfnl](https://github.com/jrfnl).
13 |
14 | ## [v0.5] - 2020-08-17
15 |
16 | ### Added
17 |
18 | - Added `--custom-function` parameter to check custom debug functions [#10](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/10) from [@umutphp](https://github.com/umutphp).
19 | - Added .gitattributes from [@reedy](https://github.com/reedy).
20 |
21 | ### Fixed
22 |
23 | - PHP 7.4: fix compatibility issue [#7](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/7) from [@jrfnl](https://github.com/jrfnl).
24 |
25 | ### Internal
26 |
27 | - Replaced array syntax with short array syntax from [@peter279k](https://github.com/peter279k).
28 | - Added EOF (end of file) for some PHP files from [@peter279k](https://github.com/peter279k).
29 | - Removed $loader variable on bootstrap.php file because it's unused from [@peter279k](https://github.com/peter279k).
30 | - To be compatible with future PHPUnit version, using the ^4.8.36 version at least from [@peter279k](https://github.com/peter279k).
31 | - Changed namespace to PHPunit\Framework\TestCase class namesapce from [@peter279k](https://github.com/peter279k).
32 | - Composer: allow installation of more recent Parallel Lint [#9](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/9) from [@jrfnl](https://github.com/jrfnl).
33 | - Travis: removed sudo [#8](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/8) from [@jrfnl](https://github.com/jrfnl).
34 | - Travis: removed Composer option `--prefer-source` [#8](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/pull/8) from [@jrfnl](https://github.com/jrfnl).
35 |
36 | ## [v0.4] - 2020-04-25
37 |
38 | ### Added
39 |
40 | - Added check for Symfony dump function `dd` from [@antograssiot](https://github.com/antograssiot).
41 | - Added check for Laravel dump function `dump` from [@Douglasdc3](https://github.com/Douglasdc3).
42 | - Added changelog.
43 | - Added support for PHP 7.4.
44 |
45 | ### Internal
46 |
47 | - Fixed running tests in PHP 5.4 and PHP 5.5 in CI.
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012, Jakub Onderka
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
24 | The views and conclusions contained in the software and documentation are those
25 | of the authors and should not be interpreted as representing official policies,
26 | either expressed or implied, of the FreeBSD Project.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PHP VarDump Check
2 | =================
3 |
4 | PHP console application for find forgotten variable dump. Support PHP build in method
5 | `print_r`, `var_dump` and `var_export` method and also method from Tracy debugger, Ladybug,
6 | Symfony, Laravel, Doctrine and Zend Framework.
7 |
8 | Install
9 | -------
10 |
11 | Just create a `composer.json` file and run the `php composer.phar install` command to install it:
12 |
13 | ```json
14 | {
15 | "require-dev": {
16 | "php-parallel-lint/php-var-dump-check": "~0.4"
17 | }
18 | }
19 | ```
20 |
21 | For colored output install suggested package `php-parallel-lint/php-console-highlighter`.
22 |
23 | Usage and example output
24 | --------------
25 |
26 | ```
27 | $ ./vendor/bin/var-dump-check --no-colors --tracy .
28 | ...................X...
29 |
30 | Checked 23 files in 0.1 second, dump found in 1 file
31 |
32 | ------------------------------------------------------------
33 | Forgotten dump 'var_dump' found in ./test.php:36
34 | 34| $functionsToCheck = $this->prepareFunctionCheck($this->settings->functionsToCheck);
35 | 35|
36 | > 36| var_dump($functionsToCheck);
37 | 37|
38 | 38| foreach ($tokens as $key => $token) {
39 | ```
40 |
41 | Options for run
42 | ---------------
43 |
44 | - none - check dump: `var_dump`, `var_export`, `print_r`
45 | - `--ladybug` - check dump: `ladybug_dump`, `ladybug_dump_die`, `ld`, `ldd`
46 | - `--tracy` - check dump: `dump`, `bdump`, `Debugger::dump`, `Debugger::barDump`
47 | - `--zend` - check dump: `Zend_Debug::dump`, `\Zend\Debug\Debug::dump`
48 | - `--doctrine` - check dump: `Doctrine::dump`, `\Doctrine\Common\Util\Debug::dump`
49 | - `--symfony` - check dump: `dump`, `VarDumper::dump`, `VarDumper::setHandler`, `VarDumper::dd`
50 | - `--laravel` - check dump: `dd`, `dump`
51 | - `--no-colors` - disable colors from output
52 | - `--exclude folder/` - exclude *folder/* from check
53 | - `--extensions php,phpt,php7` - map file extensions for check
54 |
55 | Recommended setting for usage with Symfony framework
56 | --------------
57 |
58 | For run from command line:
59 |
60 | ```
61 | $ ./vendor/bin/var-dump-check --symfony --exclude app --exclude vendor .
62 | ```
63 |
64 | or setting for ANT:
65 |
66 | ```xml
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | ```
79 |
80 | ------
81 |
82 | [](https://github.com/php-parallel-lint/PHP-Var-Dump-Check/actions/workflows/test.yml)
83 | [](https://packagist.org/packages/php-parallel-lint/php-var-dump-check)
84 | [](https://packagist.org/packages/php-parallel-lint/php-var-dump-check)
85 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "php-parallel-lint/php-var-dump-check",
3 | "license": "BSD-2-Clause",
4 | "description": "Find forgotten variables dump in PHP source code.",
5 | "authors": [
6 | {
7 | "name": "Jakub Onderka",
8 | "email": "jakub.onderka@gmail.com"
9 | }
10 | ],
11 | "autoload": {
12 | "psr-4": {"JakubOnderka\\PhpVarDumpCheck\\": "src/"}
13 | },
14 | "require": {
15 | "php": ">=5.4.0"
16 | },
17 | "suggest": {
18 | "php-parallel-lint/php-console-highlighter": "For colored console output"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "^4.8.36 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0",
22 | "php-parallel-lint/php-parallel-lint": "^1.0"
23 | },
24 | "bin": ["var-dump-check"],
25 | "replace": {
26 | "jakub-onderka/php-var-dump-check": "*"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/ArrayIterator.php:
--------------------------------------------------------------------------------
1 | next();
9 | return $this->current();
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Checker.php:
--------------------------------------------------------------------------------
1 | settings = $settings;
12 | }
13 |
14 | /**
15 | * @param string $content
16 | * @return Result[]
17 | */
18 | public function check($content)
19 | {
20 | $tokens = $this->tokenize($content);
21 | $results = $this->checkForDumps($tokens);
22 |
23 | return $results;
24 | }
25 |
26 | /**
27 | * @param array $tokens
28 | * @return Result[]
29 | */
30 | protected function checkForDumps(array $tokens)
31 | {
32 | $results = [];
33 |
34 | $functionsToCheck = $this->prepareFunctionCheck($this->settings->functionsToCheck);
35 |
36 | foreach ($tokens as $key => $token) {
37 | if (
38 | is_array($token) &&
39 | (($token[0] === T_STRING && isset($functionsToCheck[$token[1]])) || isset($functionsToCheck[$token[0]]))
40 | ) {
41 | if (
42 | !$this->checkPrevTokens($tokens, $key) ||
43 | !$this->checkNextTokens($tokens, $functionsToCheck, $key)
44 | ) {
45 | continue;
46 | }
47 |
48 | $conditions = $this->settings->getFunctionCondition($token[1]);
49 | list($prediction, $sure) = $this->checkFunctionCall($tokens, $key, $conditions);
50 |
51 | if ($prediction === true || $sure === false) {
52 | $results[] = new Result($token[1], $token[2], $sure);
53 | }
54 | }
55 | }
56 |
57 | return $results;
58 | }
59 |
60 | /**
61 | * @param array $tokens
62 | * @param int $key
63 | * @return bool
64 | */
65 | protected function checkPrevTokens(array $tokens, $key)
66 | {
67 | $prevToken = $tokens[$key - 1];
68 |
69 | if (is_array($prevToken)) {
70 | return $prevToken[0] === T_OPEN_TAG || $prevToken[0] === T_OPEN_TAG_WITH_ECHO || $prevToken[0] === T_NS_SEPARATOR;
71 | } else {
72 | return $prevToken === '{' || $prevToken === ';' || $prevToken === '}';
73 | }
74 | }
75 |
76 | /**
77 | * @param array $tokens
78 | * @param array $functionsToCheck
79 | * @param int $key
80 | * @return bool
81 | */
82 | protected function checkNextTokens(array $tokens, array $functionsToCheck, $key)
83 | {
84 | $next = &$functionsToCheck;
85 |
86 | do {
87 | $currentToken = $tokens[$key++];
88 |
89 | if (!is_array($currentToken)) {
90 | return false;
91 | }
92 |
93 | if ($currentToken[0] === T_STRING && isset($next[$currentToken[1]])) {
94 | $next = &$next[$currentToken[1]];
95 | } else if (isset($next[$currentToken[0]])) {
96 | $next = &$next[$currentToken[0]];
97 | } else {
98 | return false;
99 | }
100 |
101 | if (empty($next)) {
102 | return true;
103 | }
104 | } while (true);
105 | }
106 |
107 | /**
108 | * @param array $tokens
109 | * @param int $from
110 | * @param FunctionConditions|null $conditions
111 | * @return array
112 | */
113 | protected function checkFunctionCall(array $tokens, $from, FunctionConditions $conditions = null)
114 | {
115 | /** @var FunctionArgument[] $arguments */
116 | list($ok, $arguments) = $this->checkIsFunctionCall($tokens, $from);
117 |
118 | if (!$ok) {
119 | return [false, true];
120 | }
121 |
122 | if ($conditions) {
123 | if (isset($arguments[$conditions->getArgumentNumber() - 1])) {
124 | list($isTrue, $sure) = $arguments[$conditions->getArgumentNumber() - 1]->isTrue();
125 | return [$isTrue === $conditions->getMustBe(), $sure];
126 | } else {
127 | return $conditions->getMustBe() === $conditions->getDefault() ? [true, true] : [false, true];
128 | }
129 | }
130 |
131 | return [true, true];
132 | }
133 |
134 | /**
135 | * @param array $tokens
136 | * @param int $from
137 | * @return array
138 | */
139 | protected function checkIsFunctionCall(array $tokens, $from)
140 | {
141 | $arguments = [];
142 |
143 | $count = 0;
144 | $argumentFrom = 0;
145 |
146 | for ($i = $from + 1; $i < count($tokens); $i++) {
147 | if ($tokens[$i] === '(') {
148 | $count++;
149 | if ($count === 1) {
150 | $argumentFrom = $i + 1;
151 | }
152 | } else if ($tokens[$i] === ')') {
153 | if (--$count === 0) {
154 | $arguments[] = new FunctionArgument(array_slice($tokens, $argumentFrom, $i - $argumentFrom));
155 | return [true, $arguments];
156 | }
157 | } else if ($tokens[$i] === ',' && $count === 1) {
158 | $arguments[] = new FunctionArgument(array_slice($tokens, $argumentFrom, $i - $argumentFrom));
159 | $argumentFrom = $i + 1;
160 | }
161 | }
162 |
163 | return [false, $arguments];
164 | }
165 |
166 | /**
167 | * @param string $content
168 | * @return array
169 | */
170 | protected function tokenize($content)
171 | {
172 | $tokens = token_get_all($content);
173 | $tokens = array_values(array_filter($tokens, function ($token) {
174 | return !is_array($token) || $token[0] !== T_WHITESPACE;
175 | }));
176 |
177 | return $tokens;
178 | }
179 |
180 | /**
181 | * @param array $functionsToCheck
182 | * @return array
183 | */
184 | protected function prepareFunctionCheck(array $functionsToCheck)
185 | {
186 | $output = [];
187 |
188 | foreach ($functionsToCheck as $function) {
189 | $namespaces = explode('\\', $function);
190 |
191 | $next = &$output;
192 |
193 | foreach ($namespaces as $key => $namespace) {
194 | if (strpos($namespace, '::') !== false) {
195 | list($first, $second) = explode('::', $namespace);
196 |
197 | if (!isset($next[$first])) {
198 | $next[$first] = [];
199 | }
200 | $next = &$next[$first];
201 |
202 | if (!isset($next[T_DOUBLE_COLON])) {
203 | $next[T_DOUBLE_COLON] = [];
204 | }
205 | $next = &$next[T_DOUBLE_COLON];
206 |
207 | if (!isset($next[$second])) {
208 | $next[$second] = [];
209 | }
210 | $next = &$next[$second];
211 | } else if (!empty($namespace)) {
212 | if (!isset($next[$namespace])) {
213 | $next[$namespace] = [];
214 | }
215 | $next = &$next[$namespace];
216 |
217 | if (isset($namespaces[$key + 1])) {
218 | if (!isset($next[T_NS_SEPARATOR])) {
219 | $next[T_NS_SEPARATOR] = [];
220 | }
221 | $next = &$next[T_NS_SEPARATOR];
222 | }
223 | } else {
224 | if (!isset($next[T_NS_SEPARATOR])) {
225 | $next[T_NS_SEPARATOR] = [];
226 | }
227 | $next = &$next[T_NS_SEPARATOR];
228 | }
229 | }
230 | }
231 |
232 | return $output;
233 | }
234 | }
235 |
236 |
237 |
--------------------------------------------------------------------------------
/src/Exception/Exception.php:
--------------------------------------------------------------------------------
1 | argument = $argument;
12 | }
13 |
14 | /**
15 | * @return string
16 | */
17 | public function getArgument()
18 | {
19 | return $this->argument;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Exception/NotExistsPath.php:
--------------------------------------------------------------------------------
1 | path = $path;
15 | $this->message = "Path '$path' not found";
16 | }
17 |
18 | /**
19 | * @return string
20 | */
21 | public function getPath()
22 | {
23 | return $this->path;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/FunctionArgument.php:
--------------------------------------------------------------------------------
1 | tokens = $tokens;
12 | }
13 |
14 | /**
15 | * @return array
16 | */
17 | public function isTrue()
18 | {
19 | $sure = true;
20 | $prediction = null;
21 |
22 | for ($i = 0; $i < count($this->tokens); $i++) {
23 | if (is_array($this->tokens[$i])) {
24 | list($tokenType, $token) = $this->tokens[$i];
25 | $token = strtolower($token);
26 | if ($tokenType === T_COMMENT) {
27 | continue;
28 | } else if ($tokenType === T_STRING && in_array($token, ['true', 'false', 'null'])) {
29 | if ($token === 'true') {
30 | $prediction = true;
31 | } else {
32 | $prediction = false;
33 | }
34 | } else if ($tokenType === T_LNUMBER) {
35 | $prediction = $token !== '0';
36 | } else if ($tokenType === T_DNUMBER) {
37 | $prediction = $token !== '0.0';
38 | } else if ($tokenType === T_VARIABLE) {
39 | $skipTo = $this->skipVariableAssign($i + 1);
40 | if ($skipTo === false) {
41 | $sure = false;
42 | } else {
43 | $i = $skipTo;
44 | }
45 | } else {
46 | $sure = false;
47 | }
48 | } else {
49 | $sure = false;
50 | }
51 | }
52 |
53 | return [$prediction, $sure];
54 | }
55 |
56 | /**
57 | * @param int $from
58 | * @return bool
59 | */
60 | protected function skipVariableAssign($from)
61 | {
62 | for ($i = $from; $i < count($this->tokens); $i++) {
63 | if (is_array($this->tokens[$i])) {
64 | list($tokenType) = $this->tokens[$i];
65 | if ($tokenType === T_COMMENT) {
66 | continue;
67 | }
68 | } else if ($this->tokens[$i] === '=') {
69 | return $i;
70 | } else {
71 | return false;
72 | }
73 | }
74 |
75 | return false;
76 | }
77 | }
--------------------------------------------------------------------------------
/src/FunctionConditions.php:
--------------------------------------------------------------------------------
1 | argumentNumber = $argumentNumber;
23 | $this->mustBe = $mustBe;
24 | $this->default = $default;
25 | }
26 |
27 | /**
28 | * @return int
29 | */
30 | public function getArgumentNumber()
31 | {
32 | return $this->argumentNumber;
33 | }
34 |
35 | /**
36 | * @return boolean
37 | */
38 | public function getDefault()
39 | {
40 | return $this->default;
41 | }
42 |
43 | /**
44 | * @return boolean
45 | */
46 | public function getMustBe()
47 | {
48 | return $this->mustBe;
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Manager.php:
--------------------------------------------------------------------------------
1 | getFilesFromPaths($settings->paths, $settings->extensions, $settings->excluded);
15 | $checkedFiles = count($files);
16 |
17 | $output = $output ?: ($settings->colors ? new OutputColored(new Writer\Console) : new Output(new Writer\Console));
18 | $output->setTotalFileCount($checkedFiles);
19 |
20 | /** @var Result[] $results */
21 | $results = [];
22 |
23 | $startTime = microtime(true);
24 | $checkedFiles = 0;
25 | $filesWithDump = 0;
26 |
27 | foreach ($files as $file) {
28 | try {
29 | $fileResult = $this->checkFile($file, $settings);
30 | $checkedFiles++;
31 |
32 | if (empty($fileResult)) {
33 | $output->ok();
34 | } else {
35 | $output->error();
36 | $filesWithDump++;
37 | }
38 |
39 | $results = array_merge($results, $fileResult);
40 | } catch (Exception\Exception $e) {
41 | $output->fail();
42 | }
43 | }
44 |
45 | $runTime = round(microtime(true) - $startTime, 1);
46 |
47 | $output->writeNewLine(2);
48 |
49 | $message = "Checked $checkedFiles files in $runTime second, ";
50 | if ($filesWithDump === 0) {
51 | $message .= "no dump found.";
52 | } else {
53 | $message .= "dump found in $filesWithDump ";
54 | $message .= ($filesWithDump === 1 ? 'file' : 'files');
55 | }
56 |
57 | $output->writeLine($message);
58 |
59 | if (!empty($results)) {
60 | $output->writeNewLine();
61 |
62 | foreach ($results as $result) {
63 | $output->writeLine(str_repeat('-', 60));
64 | $output->writeResult($result);
65 | }
66 |
67 | return false;
68 | }
69 |
70 |
71 | return true;
72 | }
73 |
74 | /**
75 | * @param string $filename
76 | * @param Settings $settings
77 | * @return Result[]
78 | * @throws Exception\FileNotFound
79 | * @throws Exception\FileOpen
80 | */
81 | public function checkFile($filename, Settings $settings = null)
82 | {
83 | if ($settings === null) {
84 | $settings = new Settings();
85 | }
86 |
87 | $content = $this->loadFile($filename);
88 |
89 | $checker = new Checker($settings);
90 | $results = $checker->check($content);
91 | $this->setFilePathToResults($results, $filename);
92 |
93 | return $results;
94 | }
95 |
96 | /**
97 | * @param string $filename
98 | * @return string
99 | * @throws Exception\FileOpen
100 | * @throws Exception\FileNotFound
101 | */
102 | protected function loadFile($filename)
103 | {
104 | if (!file_exists($filename)) {
105 | throw new Exception\FileNotFound("File '$filename' was not found.'");
106 | }
107 |
108 | $content = file_get_contents($filename);
109 |
110 | if ($content === false) {
111 | throw new Exception\FileOpen("Can not open file '$filename'.");
112 | }
113 |
114 | return $content;
115 | }
116 |
117 | /**
118 | * @param array $paths
119 | * @param array $extensions
120 | * @param array $excluded
121 | * @return array
122 | * @throws Exception\NotExistsPath
123 | */
124 | protected function getFilesFromPaths(array $paths, array $extensions, array $excluded = [])
125 | {
126 | $extensions = array_flip($extensions);
127 | $files = [];
128 |
129 | foreach ($paths as $path) {
130 | if (is_file($path)) {
131 | $files[] = $path;
132 | } else if (is_dir($path)) {
133 | $iterator = new \RecursiveDirectoryIterator($path);
134 | if (!empty($excluded)) {
135 | $iterator = new RecursiveDirectoryFilterIterator($iterator, $excluded);
136 | }
137 | $iterator = new \RecursiveIteratorIterator($iterator);
138 |
139 | /** @var \SplFileInfo[] $iterator */
140 | foreach ($iterator as $directoryFile) {
141 | if (isset($extensions[pathinfo($directoryFile->getFilename(), PATHINFO_EXTENSION)])) {
142 | $files[] = (string) $directoryFile;
143 | }
144 | }
145 | } else {
146 | throw new Exception\NotExistsPath($path);
147 | }
148 | }
149 |
150 | return $files;
151 | }
152 |
153 | /**
154 | * @param Result[] $results
155 | * @param string $filePath
156 | */
157 | protected function setFilePathToResults(array $results, $filePath)
158 | {
159 | foreach ($results as $result) {
160 | $result->setFilePath($filePath);
161 | }
162 | }
163 | }
--------------------------------------------------------------------------------
/src/Output.php:
--------------------------------------------------------------------------------
1 | writer = $writer ?: new Writer\Console;
24 | }
25 |
26 | public function ok()
27 | {
28 | $this->writer->write('.');
29 | $this->progress();
30 | }
31 |
32 | public function error()
33 | {
34 | $this->writer->write('X');
35 | $this->progress();
36 | }
37 |
38 | public function fail()
39 | {
40 | $this->writer->write('-');
41 | $this->progress();
42 | }
43 |
44 | /**
45 | * @param string|null $line
46 | */
47 | public function writeLine($line = null)
48 | {
49 | $this->writer->write($line . PHP_EOL);
50 | }
51 |
52 | /**
53 | * @param int $count
54 | */
55 | public function writeNewLine($count = 1)
56 | {
57 | $this->writer->write(str_repeat(PHP_EOL, $count));
58 | }
59 |
60 | /**
61 | * @param int $count
62 | */
63 | public function setTotalFileCount($count)
64 | {
65 | $this->totalFileCount = $count;
66 | }
67 |
68 | /**
69 | * @param Result $result
70 | * @param bool $withCodeSnippet
71 | */
72 | public function writeResult(Result $result, $withCodeSnippet = true)
73 | {
74 | $string = "Forgotten dump '{$result->getType()}' found in {$result->getShortFilePath()}:{$result->getLineNumber()}" . PHP_EOL;
75 |
76 | if ($withCodeSnippet) {
77 | $string .= $this->getCodeSnippet(file_get_contents($result->getFilePath()), $result->getLineNumber());
78 | }
79 |
80 | $this->writer->write($string);
81 | }
82 |
83 | /**
84 | * @param string $fileContent
85 | * @param int $lineNumber
86 | * @param int $linesBefore
87 | * @param int $linesAfter
88 | * @return string
89 | */
90 | protected function getCodeSnippet($fileContent, $lineNumber, $linesBefore = 2, $linesAfter = 2)
91 | {
92 | $lines = explode("\n", $fileContent);
93 |
94 | $offset = $lineNumber - $linesBefore - 1;
95 | $offset = max($offset, 0);
96 | $length = $linesAfter + $linesBefore + 1;
97 | $lines = array_slice($lines, $offset, $length, $preserveKeys = true);
98 |
99 | end($lines);
100 | $lineStrlen = strlen(key($lines) + 1);
101 |
102 | $snippet = '';
103 | foreach ($lines as $i => $line) {
104 | $snippet .= ($lineNumber === $i + 1 ? ' > ' : ' ');
105 | $snippet .= str_pad($i + 1, $lineStrlen, ' ', STR_PAD_LEFT) . '| ' . rtrim($line) . PHP_EOL;
106 | }
107 |
108 | return $snippet;
109 | }
110 |
111 | protected function progress()
112 | {
113 | if (++$this->checkedFiles % $this->filesPerLine === 0) {
114 | if ($this->totalFileCount != 0) { // !=
115 | $percent = round($this->checkedFiles / $this->totalFileCount * 100);
116 | $current = $this->stringWidth($this->checkedFiles, strlen($this->totalFileCount));
117 | $this->writeLine(" $current/$this->totalFileCount ($percent %)");
118 | }
119 | }
120 | }
121 |
122 | /**
123 | * @param string $input
124 | * @param int $width
125 | * @return string
126 | */
127 | protected function stringWidth($input, $width = 3)
128 | {
129 | $multiplier = $width - strlen($input);
130 | return str_repeat(' ', $multiplier > 0 ? $multiplier : 0) . $input;
131 | }
132 | }
--------------------------------------------------------------------------------
/src/OutputColored.php:
--------------------------------------------------------------------------------
1 | color = new Color();
24 | }
25 |
26 | if (!$highlighter && $this->color && class_exists('\JakubOnderka\PhpConsoleHighlighter\Highlighter')) {
27 | $this->highlighter = new Highlighter($this->color);
28 | }
29 | }
30 |
31 | public function error()
32 | {
33 | if ($this->color) {
34 | $this->writer->write($this->color->apply('bg_red', 'X'));
35 | $this->progress();
36 | } else {
37 | parent::error();
38 | }
39 | }
40 |
41 | /**
42 | * @param string $fileContent
43 | * @param int $lineNumber
44 | * @param int $linesBefore
45 | * @param int $linesAfter
46 | * @return string
47 | */
48 | protected function getCodeSnippet($fileContent, $lineNumber, $linesBefore = 2, $linesAfter = 2)
49 | {
50 | if ($this->highlighter) {
51 | return $this->highlighter->getCodeSnippet($fileContent, $lineNumber, $linesBefore, $linesAfter);
52 | } else {
53 | return parent::getCodeSnippet($fileContent, $lineNumber, $linesBefore, $linesAfter);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/RecursiveDirectoryFilterIterator.php:
--------------------------------------------------------------------------------
1 | iterator = $iterator;
20 | $this->excluded = array_map([$this, 'getPathname'], $excluded);
21 | }
22 |
23 | /**
24 | * (PHP 5 >= 5.1.0)
25 | * Check whether the current element of the iterator is acceptable
26 | *
27 | * @link http://php.net/manual/en/filteriterator.accept.php
28 | * @return bool true if the current element is acceptable, otherwise false.
29 | */
30 | #[\ReturnTypeWillChange]
31 | public function accept()
32 | {
33 | $current = $this->current()->getPathname();
34 | $current = $this->normalizeDirectorySeparator($current);
35 |
36 | if ('.' . DIRECTORY_SEPARATOR !== $current[0] . $current[1]) {
37 | $current = '.' . DIRECTORY_SEPARATOR . $current;
38 | }
39 |
40 | return !in_array($current, $this->excluded);
41 | }
42 |
43 | /**
44 | * (PHP 5 >= 5.1.0)
45 | * Check whether the inner iterator's current element has children
46 | *
47 | * @link http://php.net/manual/en/recursivefilteriterator.haschildren.php
48 | * @return bool true if the inner iterator has children, otherwise false
49 | */
50 | #[\ReturnTypeWillChange]
51 | public function hasChildren()
52 | {
53 | return $this->iterator->hasChildren();
54 | }
55 |
56 | /**
57 | * (PHP 5 >= 5.1.0)
58 | * Return the inner iterator's children contained in a RecursiveFilterIterator
59 | *
60 | * @link http://php.net/manual/en/recursivefilteriterator.getchildren.php
61 | * @return \RecursiveFilterIterator containing the inner iterator's children.
62 | */
63 | #[\ReturnTypeWillChange]
64 | public function getChildren()
65 | {
66 | return new self($this->iterator->getChildren(), $this->excluded);
67 | }
68 |
69 | /**
70 | * @param string $file
71 | * @return string
72 | */
73 | private function getPathname($file)
74 | {
75 | $file = $this->normalizeDirectorySeparator($file);
76 |
77 | if ('.' . DIRECTORY_SEPARATOR !== $file[0] . $file[1]) {
78 | $file = '.' . DIRECTORY_SEPARATOR . $file;
79 | }
80 |
81 | $directoryFile = new \SplFileInfo($file);
82 | return $directoryFile->getPathname();
83 | }
84 |
85 | /**
86 | * @param string $file
87 | * @return string
88 | */
89 | private function normalizeDirectorySeparator($file)
90 | {
91 | return str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $file);
92 | }
93 | }
--------------------------------------------------------------------------------
/src/Result.php:
--------------------------------------------------------------------------------
1 | type = $type;
26 | $this->lineNumber = $lineNumber;
27 | $this->sure = $sure;
28 | }
29 |
30 | /**
31 | * @param string $filePath
32 | */
33 | public function setFilePath($filePath)
34 | {
35 | $this->filePath = $filePath;
36 | }
37 |
38 | /**
39 | * @return string
40 | */
41 | public function getType()
42 | {
43 | return $this->type;
44 | }
45 |
46 | /**
47 | * @return int
48 | */
49 | public function getLineNumber()
50 | {
51 | return $this->lineNumber;
52 | }
53 |
54 | /**
55 | * @return bool
56 | */
57 | public function isSure()
58 | {
59 | return $this->sure;
60 | }
61 |
62 | /**
63 | * @return string
64 | */
65 | public function getFilePath()
66 | {
67 | return $this->filePath;
68 | }
69 |
70 | /**
71 | * @return string
72 | */
73 | public function getShortFilePath()
74 | {
75 | return str_replace(getcwd(), '', $this->filePath);
76 | }
77 | }
--------------------------------------------------------------------------------
/src/Settings.php:
--------------------------------------------------------------------------------
1 | paths[] = $argument;
82 | } else {
83 | switch ($argument) {
84 | case '--extensions':
85 | $setting->extensions = array_map('trim', explode(',', $arguments->getNext()));
86 | break;
87 |
88 | case '--exclude':
89 | $setting->excluded[] = $arguments->getNext();
90 | break;
91 |
92 | case '--no-colors':
93 | $setting->colors = false;
94 | break;
95 |
96 | case '--tracy':
97 | $setting->functionsToCheck[] = self::DEBUGGER_DUMP;
98 | $setting->functionsToCheck[] = self::DEBUGGER_DUMP_SHORTCUT;
99 | $setting->functionsToCheck[] = self::DEBUGGER_BARDUMP;
100 | $setting->functionsToCheck[] = self::DEBUGGER_BARDUMP_SHORTCUT;
101 | break;
102 |
103 | case '--zend':
104 | $setting->functionsToCheck[] = self::ZEND_DEBUG_DUMP;
105 | $setting->functionsToCheck[] = self::ZEND_DEBUG_DUMP_2;
106 | break;
107 |
108 | case '--ladybug':
109 | $setting->functionsToCheck[] = self::LADYBUG_DUMP;
110 | $setting->functionsToCheck[] = self::LADYBUG_DUMP_DIE;
111 | $setting->functionsToCheck[] = self::LADYBUG_DUMP_SHORTCUT;
112 | $setting->functionsToCheck[] = self::LADYBUG_DUMP_DIE_SHORTCUT;
113 | break;
114 |
115 | case '--symfony':
116 | $setting->functionsToCheck[] = self::SYMFONY_VARDUMPER_DUMP;
117 | $setting->functionsToCheck[] = self::SYMFONY_VARDUMPER_DUMP_SHORTCUT;
118 | $setting->functionsToCheck[] = self::SYMFONY_VARDUMPER_DD;
119 | $setting->functionsToCheck[] = self::SYMFONY_VARDUMPER_DD_SHORTCUT;
120 | $setting->functionsToCheck[] = self::SYMFONY_VARDUMPER_HANDLER;
121 | break;
122 |
123 | case '--laravel':
124 | $setting->functionsToCheck[] = self::LARAVEL_DUMP_DD;
125 | $setting->functionsToCheck[] = self::LARAVEL_DUMP;
126 | break;
127 |
128 | case '--custom-function':
129 | $customFunctions = array_map('trim', explode(',', $arguments->getNext()));
130 | break;
131 |
132 | case '--doctrine':
133 | $setting->functionsToCheck[] = self::DOCTRINE_DUMP;
134 | $setting->functionsToCheck[] = self::DOCTRINE_DUMP_2;
135 | break;
136 |
137 | default:
138 | throw new Exception\InvalidArgument($argument);
139 | }
140 | }
141 | }
142 |
143 | // Merge if any custom function is given
144 | $setting->functionsToCheck = array_merge($setting->functionsToCheck, $customFunctions);
145 | $setting->functionsToCheck = array_unique($setting->functionsToCheck);
146 |
147 | return $setting;
148 | }
149 |
150 | /**
151 | * @param string $method
152 | * @return FunctionConditions
153 | */
154 | public function getFunctionCondition($method)
155 | {
156 | $functionConditions = [
157 | self::VAR_DUMP => new FunctionConditions(2, false, false),
158 | self::PRINT_R => new FunctionConditions(2, false, false),
159 | self::VAR_EXPORT => new FunctionConditions(2, false, false),
160 | self::ZEND_DEBUG_DUMP => new FunctionConditions(3, true, true),
161 | self::DEBUGGER_DUMP => new FunctionConditions(2, false, false),
162 | self::DOCTRINE_DUMP => new FunctionConditions(2, false, false),
163 | ];
164 |
165 |
166 | if (!isset($functionConditions[$method])) {
167 | return null;
168 | }
169 |
170 | return $functionConditions[$method];
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/src/Writer/Console.php:
--------------------------------------------------------------------------------
1 | logFile = $logFile;
18 | }
19 |
20 | /**
21 | * @param string $string
22 | */
23 | public function write($string)
24 | {
25 | $this->buffer .= $string;
26 | }
27 |
28 | public function __destruct()
29 | {
30 | file_put_contents($this->logFile, $this->buffer);
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Writer/Multiple.php:
--------------------------------------------------------------------------------
1 | addWriter($writer);
16 | }
17 | }
18 |
19 | /**
20 | * @param Writer $writer
21 | */
22 | public function addWriter(Writer $writer)
23 | {
24 | $this->writers[] = $writer;
25 | }
26 |
27 | /**
28 | * @param string $string
29 | */
30 | public function write($string)
31 | {
32 | foreach ($this->writers as $writer) {
33 | $writer->write($string);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Writer/Writer.php:
--------------------------------------------------------------------------------
1 |
17 | Options:
18 | --tracy Enable support for Tracy (Debugger::dump)
19 | --zend Enable support for Zend (Zend_Debug::dump and \Zend\Debug\Debug::dump)
20 | --ladybug Enable support for Ladybug (ladybug_dump, ladybug_dump_die, ld, ldd)
21 | --symfony Enable support for Symfony2 (dump, VarDumper::dump, VarDumper::setHandler, Vardumper::dd())
22 | --doctrine Enable support for Doctrine (Doctrine::dump, \Doctrine\Common\Util\Debug::dump)
23 | --laravel Enable support for Laravel (dd, dump)
24 | --custom-function Comma separated custom function name(s) to check like "pre_echo".
25 | --extensions Check only files with selected extensions separated by comma
26 | (default: php, php3, php4, php5, phtml)
27 | --exclude Exclude directory. If you want exclude multiple directory, use
28 | multiple exclude parameters.
29 | --no-colors Disable colors in console output.
30 | -V, --version Show version.
31 | -h, --help Print this help.
32 |
37 | PHP Var Dump check version = VERSION ?>
38 | ---------------------------
39 | Usage:
40 | var-dump-check [files or directories]
41 | getArgument()}" . PHP_EOL);
79 | echo PHP_EOL;
80 | showOptions();
81 | die(FAILED);
82 | }
83 |
84 | try {
85 | $check = new PhpVarDumpCheck\Manager();
86 | $status = $check->check($settings);
87 | die($status ? SUCCESS : WITH_ERRORS);
88 | } catch (PhpVarDumpCheck\Exception\Exception $e) {
89 | fwrite(STDERR, $e->getMessage() . PHP_EOL);
90 | die(FAILED);
91 | }
92 |
--------------------------------------------------------------------------------