🔧
This commit is contained in:
21
vendor/spatie/backtrace/README.md
vendored
21
vendor/spatie/backtrace/README.md
vendored
@@ -62,16 +62,17 @@ A `Spatie\Backtrace\Frame` has these properties:
|
||||
- `arguments`: the arguments used for this frame. Will be `null` if `withArguments` was not used.
|
||||
- `class`: the class name for this frame. Will be `null` if the frame concerns a function.
|
||||
- `method`: the method used in this frame
|
||||
- `object`: the object when the frame is in an object context (method call, closure bound to object, arrow function which captured `$this`, etc.). Will be `null` if `withObject` was not used.
|
||||
- `applicationFrame`: contains `true` is this frame belongs to your application, and `false` if it belongs to a file in
|
||||
the vendor directory
|
||||
|
||||
### Collecting arguments
|
||||
### Collecting arguments and objects
|
||||
|
||||
For performance reasons, the frames of the back trace will not contain the arguments of the called functions. If you
|
||||
want to add those use the `withArguments` method.
|
||||
For performance reasons, the frames of the back trace will not contain the arguments of the called functions and the
|
||||
object. If you want to add those, use the `withArguments` and `withObject` methods.
|
||||
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->withArguments();
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->withArguments()->withObject();
|
||||
```
|
||||
|
||||
#### Reducing arguments
|
||||
@@ -123,6 +124,13 @@ frame is an application frame, or a vendor frame. Here's an example using a Lara
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->applicationPath(base_path());
|
||||
```
|
||||
### Removing the application path from the file name
|
||||
|
||||
You can use `trimFilePaths` to remove the base path of your app from the file. This will only work if you use it in conjunction with the `applicationPath` method re above. Here's an example using a Laravel specific function. This will ensure the Frame has the trimmedFilePath property set.
|
||||
|
||||
```php
|
||||
$backtrace = Backtrace::create()->applicationPath(base_path())->trimFilePaths());
|
||||
```
|
||||
|
||||
### Getting a certain part of a trace
|
||||
|
||||
@@ -168,7 +176,10 @@ Here's how you can get a backtrace for a throwable.
|
||||
$frames = Spatie\Backtrace\Backtrace::createForThrowable($throwable)
|
||||
```
|
||||
|
||||
Because we will use the backtrace that is already available the throwable, the frames will always contain the arguments used.
|
||||
Because we will use the backtrace that is already available in the throwable, the frames will contain the arguments used
|
||||
in the backtrace as long as the `zend.exception_ignore_args` INI option is disabled (set to `0`) *before* the throwable
|
||||
is thrown. On the other hand, objects will never be included in the backtrace.
|
||||
[More information](https://www.php.net/manual/en/throwable.gettrace.php#129087).
|
||||
|
||||
## Testing
|
||||
|
||||
|
||||
49
vendor/spatie/backtrace/composer.json
vendored
49
vendor/spatie/backtrace/composer.json
vendored
@@ -1,12 +1,11 @@
|
||||
{
|
||||
"name": "spatie/backtrace",
|
||||
"description": "A better backtrace",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"spatie",
|
||||
"backtrace"
|
||||
],
|
||||
"homepage": "https://github.com/spatie/backtrace",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van de Herten",
|
||||
@@ -15,15 +14,29 @@
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"homepage": "https://github.com/spatie/backtrace",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/spatie"
|
||||
},
|
||||
{
|
||||
"type": "other",
|
||||
"url": "https://spatie.be/open-source/support-us"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"spatie/phpunit-snapshot-assertions": "^4.2",
|
||||
"symfony/var-dumper": "^5.1"
|
||||
"laravel/serializable-closure": "^1.3 || ^2.0",
|
||||
"phpunit/phpunit": "^9.3 || ^11.4.3",
|
||||
"spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6",
|
||||
"symfony/var-dumper": "^5.1 || ^6.0 || ^7.0"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Backtrace\\": "src"
|
||||
@@ -34,25 +47,13 @@
|
||||
"Spatie\\Backtrace\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"psalm": "vendor/bin/psalm",
|
||||
"test": "vendor/bin/phpunit",
|
||||
"test-coverage": "vendor/bin/phpunit --coverage-html coverage",
|
||||
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/spatie"
|
||||
},
|
||||
{
|
||||
"type": "other",
|
||||
"url": "https://spatie.be/open-source/support-us"
|
||||
}
|
||||
]
|
||||
"scripts": {
|
||||
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes",
|
||||
"psalm": "vendor/bin/psalm",
|
||||
"test": "vendor/bin/phpunit",
|
||||
"test-coverage": "vendor/bin/phpunit --coverage-html coverage"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ class MinimalArrayArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if(! is_array($argument)) {
|
||||
if (! is_array($argument)) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class SymphonyRequestArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if(! $argument instanceof Request) {
|
||||
if (! $argument instanceof Request) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
|
||||
49
vendor/spatie/backtrace/src/Backtrace.php
vendored
49
vendor/spatie/backtrace/src/Backtrace.php
vendored
@@ -3,6 +3,7 @@
|
||||
namespace Spatie\Backtrace;
|
||||
|
||||
use Closure;
|
||||
use Laravel\SerializableClosure\Support\ClosureStream;
|
||||
use Spatie\Backtrace\Arguments\ArgumentReducers;
|
||||
use Spatie\Backtrace\Arguments\ReduceArgumentsAction;
|
||||
use Spatie\Backtrace\Arguments\Reducers\ArgumentReducer;
|
||||
@@ -22,6 +23,9 @@ class Backtrace
|
||||
/** @var bool */
|
||||
protected $withObject = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $trimFilePaths = false;
|
||||
|
||||
/** @var string|null */
|
||||
protected $applicationPath;
|
||||
|
||||
@@ -76,9 +80,9 @@ class Backtrace
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withObject(): self
|
||||
public function withObject(bool $withObject = true): self
|
||||
{
|
||||
$this->withObject = true;
|
||||
$this->withObject = $withObject;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -90,6 +94,13 @@ class Backtrace
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function trimFilePaths(): self
|
||||
{
|
||||
$this->trimFilePaths = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offset(int $offset): self
|
||||
{
|
||||
$this->offset = $offset;
|
||||
@@ -138,13 +149,16 @@ class Backtrace
|
||||
return $this->throwable->getTrace();
|
||||
}
|
||||
|
||||
$options = null;
|
||||
// Omit arguments and object
|
||||
$options = DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
|
||||
if (! $this->withArguments) {
|
||||
$options = $options | DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
// Populate arguments
|
||||
if ($this->withArguments) {
|
||||
$options = 0;
|
||||
}
|
||||
|
||||
if ($this->withObject()) {
|
||||
// Populate object
|
||||
if ($this->withObject) {
|
||||
$options = $options | DEBUG_BACKTRACE_PROVIDE_OBJECT;
|
||||
}
|
||||
|
||||
@@ -171,15 +185,34 @@ class Backtrace
|
||||
$reduceArgumentsAction = new ReduceArgumentsAction($this->resolveArgumentReducers());
|
||||
|
||||
foreach ($rawFrames as $rawFrame) {
|
||||
$frames[] = new Frame(
|
||||
$textSnippet = null;
|
||||
|
||||
if (
|
||||
class_exists(ClosureStream::class)
|
||||
&& substr($currentFile, 0, strlen(ClosureStream::STREAM_PROTO)) === ClosureStream::STREAM_PROTO
|
||||
) {
|
||||
$textSnippet = $currentFile;
|
||||
$currentFile = ClosureStream::STREAM_PROTO.'://function()';
|
||||
$currentLine -= 1;
|
||||
}
|
||||
|
||||
if ($this->trimFilePaths && $this->applicationPath) {
|
||||
$trimmedFilePath = str_replace($this->applicationPath, '', $currentFile);
|
||||
}
|
||||
$frame = new Frame(
|
||||
$currentFile,
|
||||
$currentLine,
|
||||
$arguments,
|
||||
$rawFrame['function'] ?? null,
|
||||
$rawFrame['class'] ?? null,
|
||||
$this->isApplicationFrame($currentFile)
|
||||
$rawFrame['object'] ?? null,
|
||||
$this->isApplicationFrame($currentFile),
|
||||
$textSnippet,
|
||||
$trimmedFilePath ?? null,
|
||||
);
|
||||
|
||||
$frames[] = $frame;
|
||||
|
||||
$arguments = $this->withArguments
|
||||
? $rawFrame['args'] ?? null
|
||||
: null;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
namespace Spatie\Backtrace\CodeSnippets;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
@@ -26,27 +26,21 @@ class CodeSnippet
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get(string $fileName): array
|
||||
public function get(SnippetProvider $provider): array
|
||||
{
|
||||
if (! file_exists($fileName)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$file = new File($fileName);
|
||||
|
||||
[$startLineNumber, $endLineNumber] = $this->getBounds($file->numberOfLines());
|
||||
[$startLineNumber, $endLineNumber] = $this->getBounds($provider->numberOfLines());
|
||||
|
||||
$code = [];
|
||||
|
||||
$line = $file->getLine($startLineNumber);
|
||||
$line = $provider->getLine($startLineNumber);
|
||||
|
||||
$currentLineNumber = $startLineNumber;
|
||||
|
||||
while ($currentLineNumber <= $endLineNumber) {
|
||||
$code[$currentLineNumber] = rtrim(substr($line, 0, 250));
|
||||
|
||||
$line = $file->getNextLine();
|
||||
$line = $provider->getNextLine();
|
||||
$currentLineNumber++;
|
||||
}
|
||||
|
||||
@@ -56,9 +50,9 @@ class CodeSnippet
|
||||
}
|
||||
}
|
||||
|
||||
public function getAsString(string $fileName): string
|
||||
public function getAsString(SnippetProvider $provider): string
|
||||
{
|
||||
$snippet = $this->get($fileName);
|
||||
$snippet = $this->get($provider);
|
||||
|
||||
$snippetStrings = array_map(function (string $line, string $number) {
|
||||
return "{$number} {$line}";
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
namespace Spatie\Backtrace\CodeSnippets;
|
||||
|
||||
use SplFileObject;
|
||||
|
||||
class File
|
||||
class FileSnippetProvider implements SnippetProvider
|
||||
{
|
||||
/** @var \SplFileObject */
|
||||
protected $file;
|
||||
@@ -21,7 +21,7 @@ class File
|
||||
return $this->file->key() + 1;
|
||||
}
|
||||
|
||||
public function getLine(int $lineNumber = null): string
|
||||
public function getLine(?int $lineNumber = null): string
|
||||
{
|
||||
if (is_null($lineNumber)) {
|
||||
return $this->getNextLine();
|
||||
67
vendor/spatie/backtrace/src/CodeSnippets/LaravelSerializableClosureSnippetProvider.php
vendored
Normal file
67
vendor/spatie/backtrace/src/CodeSnippets/LaravelSerializableClosureSnippetProvider.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\CodeSnippets;
|
||||
|
||||
class LaravelSerializableClosureSnippetProvider implements SnippetProvider
|
||||
{
|
||||
/** @var array<string> */
|
||||
protected $lines;
|
||||
|
||||
/** @var int */
|
||||
protected $counter = 0;
|
||||
|
||||
public function __construct(string $snippet)
|
||||
{
|
||||
$this->lines = preg_split("/\r\n|\n|\r/", $snippet);
|
||||
|
||||
$this->cleanupLines();
|
||||
}
|
||||
|
||||
public function numberOfLines(): int
|
||||
{
|
||||
return count($this->lines);
|
||||
}
|
||||
|
||||
public function getLine(?int $lineNumber = null): string
|
||||
{
|
||||
if (is_null($lineNumber)) {
|
||||
return $this->getNextLine();
|
||||
}
|
||||
|
||||
$this->counter = $lineNumber - 1;
|
||||
|
||||
return $this->lines[$lineNumber - 1];
|
||||
}
|
||||
|
||||
public function getNextLine(): string
|
||||
{
|
||||
$this->counter++;
|
||||
|
||||
if ($this->counter >= count($this->lines)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->lines[$this->counter];
|
||||
}
|
||||
|
||||
protected function cleanupLines(): void
|
||||
{
|
||||
$spacesOrTabsToRemove = PHP_INT_MAX;
|
||||
|
||||
for ($i = 1; $i < count($this->lines); $i++) {
|
||||
if (empty($this->lines[$i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$spacesOrTabsToRemove = min(strspn($this->lines[$i], " \t"), $spacesOrTabsToRemove);
|
||||
}
|
||||
|
||||
if ($spacesOrTabsToRemove === PHP_INT_MAX) {
|
||||
$spacesOrTabsToRemove = 0;
|
||||
}
|
||||
|
||||
for ($i = 1; $i < count($this->lines); $i++) {
|
||||
$this->lines[$i] = substr($this->lines[$i], $spacesOrTabsToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
vendor/spatie/backtrace/src/CodeSnippets/NullSnippetProvider.php
vendored
Normal file
21
vendor/spatie/backtrace/src/CodeSnippets/NullSnippetProvider.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\CodeSnippets;
|
||||
|
||||
class NullSnippetProvider implements SnippetProvider
|
||||
{
|
||||
public function numberOfLines(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getLine(?int $lineNumber = null): string
|
||||
{
|
||||
return $this->getNextLine();
|
||||
}
|
||||
|
||||
public function getNextLine(): string
|
||||
{
|
||||
return "File not found for code snippet";
|
||||
}
|
||||
}
|
||||
12
vendor/spatie/backtrace/src/CodeSnippets/SnippetProvider.php
vendored
Normal file
12
vendor/spatie/backtrace/src/CodeSnippets/SnippetProvider.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\CodeSnippets;
|
||||
|
||||
interface SnippetProvider
|
||||
{
|
||||
public function numberOfLines(): int;
|
||||
|
||||
public function getLine(?int $lineNumber = null): string;
|
||||
|
||||
public function getNextLine(): string;
|
||||
}
|
||||
47
vendor/spatie/backtrace/src/Frame.php
vendored
47
vendor/spatie/backtrace/src/Frame.php
vendored
@@ -2,11 +2,20 @@
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
|
||||
use Spatie\Backtrace\CodeSnippets\CodeSnippet;
|
||||
use Spatie\Backtrace\CodeSnippets\FileSnippetProvider;
|
||||
use Spatie\Backtrace\CodeSnippets\LaravelSerializableClosureSnippetProvider;
|
||||
use Spatie\Backtrace\CodeSnippets\NullSnippetProvider;
|
||||
use Spatie\Backtrace\CodeSnippets\SnippetProvider;
|
||||
|
||||
class Frame
|
||||
{
|
||||
/** @var string */
|
||||
public $file;
|
||||
|
||||
/** @var string|null */
|
||||
public $trimmedFilePath;
|
||||
|
||||
/** @var int */
|
||||
public $lineNumber;
|
||||
|
||||
@@ -22,16 +31,27 @@ class Frame
|
||||
/** @var string|null */
|
||||
public $class;
|
||||
|
||||
/** @var object|null */
|
||||
public $object;
|
||||
|
||||
/** @var string|null */
|
||||
protected $textSnippet;
|
||||
|
||||
public function __construct(
|
||||
string $file,
|
||||
int $lineNumber,
|
||||
?array $arguments,
|
||||
string $method = null,
|
||||
string $class = null,
|
||||
bool $isApplicationFrame = false
|
||||
?string $method = null,
|
||||
?string $class = null,
|
||||
?object $object = null,
|
||||
bool $isApplicationFrame = false,
|
||||
?string $textSnippet = null,
|
||||
?string $trimmedFilePath = null
|
||||
) {
|
||||
$this->file = $file;
|
||||
|
||||
$this->trimmedFilePath = $trimmedFilePath;
|
||||
|
||||
$this->lineNumber = $lineNumber;
|
||||
|
||||
$this->arguments = $arguments;
|
||||
@@ -40,7 +60,11 @@ class Frame
|
||||
|
||||
$this->class = $class;
|
||||
|
||||
$this->object = $object;
|
||||
|
||||
$this->applicationFrame = $isApplicationFrame;
|
||||
|
||||
$this->textSnippet = $textSnippet;
|
||||
}
|
||||
|
||||
public function getSnippet(int $lineCount): array
|
||||
@@ -48,7 +72,7 @@ class Frame
|
||||
return (new CodeSnippet())
|
||||
->surroundingLine($this->lineNumber)
|
||||
->snippetLineCount($lineCount)
|
||||
->get($this->file);
|
||||
->get($this->getCodeSnippetProvider());
|
||||
}
|
||||
|
||||
public function getSnippetAsString(int $lineCount): string
|
||||
@@ -56,7 +80,7 @@ class Frame
|
||||
return (new CodeSnippet())
|
||||
->surroundingLine($this->lineNumber)
|
||||
->snippetLineCount($lineCount)
|
||||
->getAsString($this->file);
|
||||
->getAsString($this->getCodeSnippetProvider());
|
||||
}
|
||||
|
||||
public function getSnippetProperties(int $lineCount): array
|
||||
@@ -70,4 +94,17 @@ class Frame
|
||||
];
|
||||
}, array_keys($snippet));
|
||||
}
|
||||
|
||||
protected function getCodeSnippetProvider(): SnippetProvider
|
||||
{
|
||||
if ($this->textSnippet) {
|
||||
return new LaravelSerializableClosureSnippetProvider($this->textSnippet);
|
||||
}
|
||||
|
||||
if (@file_exists($this->file)) {
|
||||
return new FileSnippetProvider($this->file);
|
||||
}
|
||||
|
||||
return new NullSnippetProvider();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user