first commit
This commit is contained in:
21
vendor/spatie/backtrace/LICENSE.md
vendored
Normal file
21
vendor/spatie/backtrace/LICENSE.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Spatie bvba <info@spatie.be>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
198
vendor/spatie/backtrace/README.md
vendored
Normal file
198
vendor/spatie/backtrace/README.md
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
# A better PHP backtrace
|
||||
|
||||
[](https://packagist.org/packages/spatie/backtrace)
|
||||

|
||||
[](https://packagist.org/packages/spatie/backtrace)
|
||||
|
||||
To get the backtrace in PHP you can use the `debug_backtrace` function. By default, it can be hard to work with. The
|
||||
reported function name for a frame is skewed: it belongs to the previous frame. Also, options need to be passed using a bitmask.
|
||||
|
||||
This package provides a better way than `debug_backtrace` to work with a back trace. Here's an example:
|
||||
|
||||
```php
|
||||
// returns an array with `Spatie\Backtrace\Frame` instances
|
||||
$frames = Spatie\Backtrace\Backtrace::create()->frames();
|
||||
|
||||
$firstFrame = $frames[0];
|
||||
|
||||
$firstFrame->file; // returns the file name
|
||||
$firstFrame->lineNumber; // returns the line number
|
||||
$firstFrame->class; // returns the class name
|
||||
```
|
||||
|
||||
## Support us
|
||||
|
||||
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/backtrace.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/backtrace)
|
||||
|
||||
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can
|
||||
support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
|
||||
|
||||
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.
|
||||
You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards
|
||||
on [our virtual postcard wall](https://spatie.be/open-source/postcards).
|
||||
|
||||
## Installation
|
||||
|
||||
You can install the package via composer:
|
||||
|
||||
```bash
|
||||
composer require spatie/backtrace
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
This is how you can create a backtrace instance:
|
||||
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create();
|
||||
```
|
||||
|
||||
### Getting the frames
|
||||
|
||||
To get all the frames you can call `frames`.
|
||||
|
||||
```php
|
||||
$frames = $backtrace->frames(); // contains an array with `Spatie\Backtrace\Frame` instances
|
||||
```
|
||||
|
||||
A `Spatie\Backtrace\Frame` has these properties:
|
||||
|
||||
- `file`: the name of the file
|
||||
- `lineNumber`: the line number
|
||||
- `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
|
||||
- `applicationFrame`: contains `true` is this frame belongs to your application, and `false` if it belongs to a file in
|
||||
the vendor directory
|
||||
|
||||
### Collecting arguments
|
||||
|
||||
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.
|
||||
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->withArguments();
|
||||
```
|
||||
|
||||
#### Reducing arguments
|
||||
|
||||
For viewing purposes, arguments can be reduced to a string:
|
||||
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->withArguments()->reduceArguments();
|
||||
```
|
||||
|
||||
By default, some typical types will be reduced to a string. You can define your own reduction algorithm per type by implementing an `ArgumentReducer`:
|
||||
|
||||
```php
|
||||
class DateTimeWithOtherFormatArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof DateTimeInterface) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
$argument->format('d/m/y H:i'),
|
||||
get_class($argument),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is a copy of the built-in argument reducer for `DateTimeInterface` where we've updated the format. An `UnReducedArgument` object is returned when the argument is not of the expected type. A `ReducedArgument` object is returned with the reduced value of the argument and the original type of the argument.
|
||||
|
||||
The reducer can be used as such:
|
||||
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->withArguments()->reduceArguments(
|
||||
Spatie\Backtrace\Arguments\ArgumentReducers::default([
|
||||
new DateTimeWithOtherFormatArgumentReducer()
|
||||
])
|
||||
);
|
||||
```
|
||||
|
||||
Which will first execute the new reducer and then the default ones.
|
||||
|
||||
### Setting the application path
|
||||
|
||||
You can use the `applicationPath` to pass the base path of your app. This value will be used to determine whether a
|
||||
frame is an application frame, or a vendor frame. Here's an example using a Laravel specific function.
|
||||
|
||||
```php
|
||||
$backtrace = Spatie\Backtrace\Backtrace::create()->applicationPath(base_path());
|
||||
```
|
||||
|
||||
### Getting a certain part of a trace
|
||||
|
||||
If you only want to have the frames starting from a particular frame in the backtrace you can use
|
||||
the `startingFromFrame` method:
|
||||
|
||||
```php
|
||||
use Spatie\Backtrace\Backtrace;
|
||||
use Spatie\Backtrace\Frame;
|
||||
|
||||
$frames = Backtrace::create()
|
||||
->startingFromFrame(function (Frame $frame) {
|
||||
return $frame->class === MyClass::class;
|
||||
})
|
||||
->frames();
|
||||
```
|
||||
|
||||
With this code, all frames before the frame that concerns `MyClass` will have been filtered out.
|
||||
|
||||
Alternatively, you can use the `offset` method, which will skip the given number of frames. In this example the first 2 frames will not end up in `$frames`.
|
||||
|
||||
```php
|
||||
$frames = Spatie\Backtrace\Backtrace::create()
|
||||
->offset(2)
|
||||
->frames();
|
||||
```
|
||||
|
||||
### Limiting the number of frames
|
||||
|
||||
To only get a specific number of frames use the `limit` function. In this example, we'll only get the first two frames.
|
||||
|
||||
```php
|
||||
$frames = Spatie\Backtrace\Backtrace::create()
|
||||
->limit(2)
|
||||
->frames();
|
||||
```
|
||||
|
||||
### Getting a backtrace for a throwable
|
||||
|
||||
Here's how you can get a backtrace for a throwable.
|
||||
|
||||
```php
|
||||
$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.
|
||||
|
||||
## Testing
|
||||
|
||||
``` bash
|
||||
composer test
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
|
||||
|
||||
## Credits
|
||||
|
||||
- [Freek Van de Herten](https://github.com/freekmurze)
|
||||
- [All Contributors](../../contributors)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
58
vendor/spatie/backtrace/composer.json
vendored
Normal file
58
vendor/spatie/backtrace/composer.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "spatie/backtrace",
|
||||
"description": "A better backtrace",
|
||||
"keywords": [
|
||||
"spatie",
|
||||
"backtrace"
|
||||
],
|
||||
"homepage": "https://github.com/spatie/backtrace",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van de Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"spatie/phpunit-snapshot-assertions": "^4.2",
|
||||
"symfony/var-dumper": "^5.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Backtrace\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
81
vendor/spatie/backtrace/src/Arguments/ArgumentReducers.php
vendored
Normal file
81
vendor/spatie/backtrace/src/Arguments/ArgumentReducers.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments;
|
||||
|
||||
use Spatie\Backtrace\Arguments\Reducers\ArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\ArrayArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\BaseTypeArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\ClosureArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\DateTimeArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\DateTimeZoneArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\EnumArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\MinimalArrayArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\SensitiveParameterArrayReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\StdClassArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\StringableArgumentReducer;
|
||||
use Spatie\Backtrace\Arguments\Reducers\SymphonyRequestArgumentReducer;
|
||||
|
||||
class ArgumentReducers
|
||||
{
|
||||
/** @var array<int, ArgumentReducer> */
|
||||
public $argumentReducers = [];
|
||||
|
||||
/**
|
||||
* @param array<ArgumentReducer|class-string<ArgumentReducer>> $argumentReducers
|
||||
*/
|
||||
public static function create(array $argumentReducers): self
|
||||
{
|
||||
return new self(array_map(
|
||||
function ($argumentReducer) {
|
||||
/** @var $argumentReducer ArgumentReducer|class-string<ArgumentReducer> */
|
||||
return $argumentReducer instanceof ArgumentReducer ? $argumentReducer : new $argumentReducer();
|
||||
},
|
||||
$argumentReducers
|
||||
));
|
||||
}
|
||||
|
||||
public static function default(array $extra = []): self
|
||||
{
|
||||
return new self(static::defaultReducers($extra));
|
||||
}
|
||||
|
||||
public static function minimal(array $extra = []): self
|
||||
{
|
||||
return new self(static::minimalReducers($extra));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, ArgumentReducer> $argumentReducers
|
||||
*/
|
||||
protected function __construct(array $argumentReducers)
|
||||
{
|
||||
$this->argumentReducers = $argumentReducers;
|
||||
}
|
||||
|
||||
protected static function defaultReducers(array $extra = []): array
|
||||
{
|
||||
return array_merge($extra, [
|
||||
new BaseTypeArgumentReducer(),
|
||||
new ArrayArgumentReducer(),
|
||||
new StdClassArgumentReducer(),
|
||||
new EnumArgumentReducer(),
|
||||
new ClosureArgumentReducer(),
|
||||
new SensitiveParameterArrayReducer(),
|
||||
new DateTimeArgumentReducer(),
|
||||
new DateTimeZoneArgumentReducer(),
|
||||
new SymphonyRequestArgumentReducer(),
|
||||
new StringableArgumentReducer(),
|
||||
]);
|
||||
}
|
||||
|
||||
protected static function minimalReducers(array $extra = []): array
|
||||
{
|
||||
return array_merge($extra, [
|
||||
new BaseTypeArgumentReducer(),
|
||||
new MinimalArrayArgumentReducer(),
|
||||
new EnumArgumentReducer(),
|
||||
new ClosureArgumentReducer(),
|
||||
new SensitiveParameterArrayReducer(),
|
||||
]);
|
||||
}
|
||||
}
|
118
vendor/spatie/backtrace/src/Arguments/ProvidedArgument.php
vendored
Normal file
118
vendor/spatie/backtrace/src/Arguments/ProvidedArgument.php
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments;
|
||||
|
||||
use ReflectionParameter;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\TruncatedReducedArgument;
|
||||
|
||||
class ProvidedArgument
|
||||
{
|
||||
/** @var string */
|
||||
public $name;
|
||||
|
||||
/** @var bool */
|
||||
public $passedByReference = false;
|
||||
|
||||
/** @var bool */
|
||||
public $isVariadic = false;
|
||||
|
||||
/** @var bool */
|
||||
public $hasDefaultValue = false;
|
||||
|
||||
/** @var mixed */
|
||||
public $defaultValue = null;
|
||||
|
||||
/** @var bool */
|
||||
public $defaultValueUsed = false;
|
||||
|
||||
/** @var bool */
|
||||
public $truncated = false;
|
||||
|
||||
/** @var mixed */
|
||||
public $reducedValue = null;
|
||||
|
||||
/** @var string|null */
|
||||
public $originalType = null;
|
||||
|
||||
public static function fromReflectionParameter(ReflectionParameter $parameter): self
|
||||
{
|
||||
return new self(
|
||||
$parameter->getName(),
|
||||
$parameter->isPassedByReference(),
|
||||
$parameter->isVariadic(),
|
||||
$parameter->isDefaultValueAvailable(),
|
||||
$parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null,
|
||||
);
|
||||
}
|
||||
|
||||
public static function fromNonReflectableParameter(
|
||||
int $index
|
||||
): self {
|
||||
return new self(
|
||||
"arg{$index}",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
public function __construct(
|
||||
string $name,
|
||||
bool $passedByReference = false,
|
||||
bool $isVariadic = false,
|
||||
bool $hasDefaultValue = false,
|
||||
$defaultValue = null,
|
||||
bool $defaultValueUsed = false,
|
||||
bool $truncated = false,
|
||||
$reducedValue = null,
|
||||
?string $originalType = null
|
||||
) {
|
||||
$this->originalType = $originalType;
|
||||
$this->reducedValue = $reducedValue;
|
||||
$this->truncated = $truncated;
|
||||
$this->defaultValueUsed = $defaultValueUsed;
|
||||
$this->defaultValue = $defaultValue;
|
||||
$this->hasDefaultValue = $hasDefaultValue;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->passedByReference = $passedByReference;
|
||||
$this->name = $name;
|
||||
|
||||
if ($this->isVariadic) {
|
||||
$this->defaultValue = [];
|
||||
}
|
||||
}
|
||||
|
||||
public function setReducedArgument(
|
||||
ReducedArgument $reducedArgument
|
||||
): self {
|
||||
$this->reducedValue = $reducedArgument->value;
|
||||
$this->originalType = $reducedArgument->originalType;
|
||||
|
||||
if ($reducedArgument instanceof TruncatedReducedArgument) {
|
||||
$this->truncated = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function defaultValueUsed(): self
|
||||
{
|
||||
$this->defaultValueUsed = true;
|
||||
$this->originalType = get_debug_type($this->defaultValue);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'value' => $this->defaultValueUsed
|
||||
? $this->defaultValue
|
||||
: $this->reducedValue,
|
||||
'original_type' => $this->originalType,
|
||||
'passed_by_reference' => $this->passedByReference,
|
||||
'is_variadic' => $this->isVariadic,
|
||||
'truncated' => $this->truncated,
|
||||
];
|
||||
}
|
||||
}
|
44
vendor/spatie/backtrace/src/Arguments/ReduceArgumentPayloadAction.php
vendored
Normal file
44
vendor/spatie/backtrace/src/Arguments/ReduceArgumentPayloadAction.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
|
||||
class ReduceArgumentPayloadAction
|
||||
{
|
||||
/** @var \Spatie\Backtrace\Arguments\ArgumentReducers */
|
||||
protected $argumentReducers;
|
||||
|
||||
public function __construct(
|
||||
ArgumentReducers $argumentReducers
|
||||
) {
|
||||
$this->argumentReducers = $argumentReducers;
|
||||
}
|
||||
|
||||
public function reduce($argument, bool $includeObjectType = false): ReducedArgument
|
||||
{
|
||||
foreach ($this->argumentReducers->argumentReducers as $reducer) {
|
||||
$reduced = $reducer->execute($argument);
|
||||
|
||||
if ($reduced instanceof ReducedArgument) {
|
||||
return $reduced;
|
||||
}
|
||||
}
|
||||
|
||||
if (gettype($argument) === 'object' && $includeObjectType) {
|
||||
return new ReducedArgument(
|
||||
'object ('.get_class($argument).')',
|
||||
get_debug_type($argument),
|
||||
);
|
||||
}
|
||||
|
||||
if (gettype($argument) === 'object') {
|
||||
return new ReducedArgument('object', get_debug_type($argument), );
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
$argument,
|
||||
get_debug_type($argument),
|
||||
);
|
||||
}
|
||||
}
|
117
vendor/spatie/backtrace/src/Arguments/ReduceArgumentsAction.php
vendored
Normal file
117
vendor/spatie/backtrace/src/Arguments/ReduceArgumentsAction.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments;
|
||||
|
||||
use ReflectionException;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use ReflectionParameter;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\VariadicReducedArgument;
|
||||
use Throwable;
|
||||
|
||||
class ReduceArgumentsAction
|
||||
{
|
||||
/** @var ArgumentReducers */
|
||||
protected $argumentReducers;
|
||||
|
||||
/** @var ReduceArgumentPayloadAction */
|
||||
protected $reduceArgumentPayloadAction;
|
||||
|
||||
public function __construct(
|
||||
ArgumentReducers $argumentReducers
|
||||
) {
|
||||
$this->argumentReducers = $argumentReducers;
|
||||
$this->reduceArgumentPayloadAction = new ReduceArgumentPayloadAction($argumentReducers);
|
||||
}
|
||||
|
||||
public function execute(
|
||||
?string $class,
|
||||
?string $method,
|
||||
?array $frameArguments
|
||||
): ?array {
|
||||
try {
|
||||
if ($frameArguments === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parameters = $this->getParameters($class, $method);
|
||||
|
||||
if ($parameters === null) {
|
||||
$arguments = [];
|
||||
|
||||
foreach ($frameArguments as $index => $argument) {
|
||||
$arguments[$index] = ProvidedArgument::fromNonReflectableParameter($index)
|
||||
->setReducedArgument($this->reduceArgumentPayloadAction->reduce($argument))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
$arguments = array_map(
|
||||
function ($argument) {
|
||||
return $this->reduceArgumentPayloadAction->reduce($argument);
|
||||
},
|
||||
$frameArguments,
|
||||
);
|
||||
|
||||
$argumentsCount = count($arguments);
|
||||
$hasVariadicParameter = false;
|
||||
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
if ($index + 1 > $argumentsCount) {
|
||||
$parameter->defaultValueUsed();
|
||||
} elseif ($parameter->isVariadic) {
|
||||
$parameter->setReducedArgument(new VariadicReducedArgument(array_slice($arguments, $index)));
|
||||
|
||||
$hasVariadicParameter = true;
|
||||
} else {
|
||||
$parameter->setReducedArgument($arguments[$index]);
|
||||
}
|
||||
|
||||
$parameters[$index] = $parameter->toArray();
|
||||
}
|
||||
|
||||
if ($this->moreArgumentsProvidedThanParameters($arguments, $parameters, $hasVariadicParameter)) {
|
||||
for ($i = count($parameters); $i < count($arguments); $i++) {
|
||||
$parameters[$i] = ProvidedArgument::fromNonReflectableParameter(count($parameters))
|
||||
->setReducedArgument($arguments[$i])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
} catch (Throwable $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return null|Array<\Spatie\Backtrace\Arguments\ProvidedArgument> */
|
||||
protected function getParameters(
|
||||
?string $class,
|
||||
?string $method
|
||||
): ?array {
|
||||
try {
|
||||
$reflection = $class !== null
|
||||
? new ReflectionMethod($class, $method)
|
||||
: new ReflectionFunction($method);
|
||||
} catch (ReflectionException $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return array_map(
|
||||
function (ReflectionParameter $reflectionParameter) {
|
||||
return ProvidedArgument::fromReflectionParameter($reflectionParameter);
|
||||
},
|
||||
$reflection->getParameters(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function moreArgumentsProvidedThanParameters(
|
||||
array $arguments,
|
||||
array $parameters,
|
||||
bool $hasVariadicParameter
|
||||
): bool {
|
||||
return count($arguments) > count($parameters) && ! $hasVariadicParameter;
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/ReducedArgument/ReducedArgument.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/ReducedArgument/ReducedArgument.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\ReducedArgument;
|
||||
|
||||
class ReducedArgument implements ReducedArgumentContract
|
||||
{
|
||||
/** @var mixed */
|
||||
public $value;
|
||||
|
||||
/** @var string */
|
||||
public $originalType;
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __construct(
|
||||
$value,
|
||||
string $originalType
|
||||
) {
|
||||
$this->originalType = $originalType;
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
8
vendor/spatie/backtrace/src/Arguments/ReducedArgument/ReducedArgumentContract.php
vendored
Normal file
8
vendor/spatie/backtrace/src/Arguments/ReducedArgument/ReducedArgumentContract.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\ReducedArgument;
|
||||
|
||||
interface ReducedArgumentContract
|
||||
{
|
||||
|
||||
}
|
8
vendor/spatie/backtrace/src/Arguments/ReducedArgument/TruncatedReducedArgument.php
vendored
Normal file
8
vendor/spatie/backtrace/src/Arguments/ReducedArgument/TruncatedReducedArgument.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\ReducedArgument;
|
||||
|
||||
class TruncatedReducedArgument extends ReducedArgument
|
||||
{
|
||||
|
||||
}
|
22
vendor/spatie/backtrace/src/Arguments/ReducedArgument/UnReducedArgument.php
vendored
Normal file
22
vendor/spatie/backtrace/src/Arguments/ReducedArgument/UnReducedArgument.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\ReducedArgument;
|
||||
|
||||
class UnReducedArgument implements ReducedArgumentContract
|
||||
{
|
||||
/** @var self|null */
|
||||
private static $instance = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function create(): self
|
||||
{
|
||||
if (self::$instance !== null) {
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
return self::$instance = new self();
|
||||
}
|
||||
}
|
21
vendor/spatie/backtrace/src/Arguments/ReducedArgument/VariadicReducedArgument.php
vendored
Normal file
21
vendor/spatie/backtrace/src/Arguments/ReducedArgument/VariadicReducedArgument.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\ReducedArgument;
|
||||
|
||||
use Exception;
|
||||
|
||||
class VariadicReducedArgument extends ReducedArgument
|
||||
{
|
||||
public function __construct(array $value)
|
||||
{
|
||||
foreach ($value as $key => $item) {
|
||||
if (! $item instanceof ReducedArgument) {
|
||||
throw new Exception('VariadicReducedArgument must be an array of ReducedArgument');
|
||||
}
|
||||
|
||||
$value[$key] = $item->value;
|
||||
}
|
||||
|
||||
parent::__construct($value, 'array');
|
||||
}
|
||||
}
|
13
vendor/spatie/backtrace/src/Arguments/Reducers/ArgumentReducer.php
vendored
Normal file
13
vendor/spatie/backtrace/src/Arguments/Reducers/ArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
|
||||
interface ArgumentReducer
|
||||
{
|
||||
/**
|
||||
* @param mixed $argument
|
||||
*/
|
||||
public function execute($argument): ReducedArgumentContract;
|
||||
}
|
52
vendor/spatie/backtrace/src/Arguments/Reducers/ArrayArgumentReducer.php
vendored
Normal file
52
vendor/spatie/backtrace/src/Arguments/Reducers/ArrayArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ArgumentReducers;
|
||||
use Spatie\Backtrace\Arguments\ReduceArgumentPayloadAction;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\TruncatedReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class ArrayArgumentReducer implements ReducedArgumentContract
|
||||
{
|
||||
/** @var int */
|
||||
protected $maxArraySize = 25;
|
||||
|
||||
/** @var \Spatie\Backtrace\Arguments\ReduceArgumentPayloadAction */
|
||||
protected $reduceArgumentPayloadAction;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->reduceArgumentPayloadAction = new ReduceArgumentPayloadAction(ArgumentReducers::minimal());
|
||||
}
|
||||
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! is_array($argument)) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return $this->reduceArgument($argument, 'array');
|
||||
}
|
||||
|
||||
protected function reduceArgument(array $argument, string $originalType): ReducedArgumentContract
|
||||
{
|
||||
foreach ($argument as $key => $value) {
|
||||
$argument[$key] = $this->reduceArgumentPayloadAction->reduce(
|
||||
$value,
|
||||
true
|
||||
)->value;
|
||||
}
|
||||
|
||||
if (count($argument) > $this->maxArraySize) {
|
||||
return new TruncatedReducedArgument(
|
||||
array_slice($argument, 0, $this->maxArraySize),
|
||||
'array'
|
||||
);
|
||||
}
|
||||
|
||||
return new ReducedArgument($argument, $originalType);
|
||||
}
|
||||
}
|
24
vendor/spatie/backtrace/src/Arguments/Reducers/BaseTypeArgumentReducer.php
vendored
Normal file
24
vendor/spatie/backtrace/src/Arguments/Reducers/BaseTypeArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class BaseTypeArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (is_int($argument)
|
||||
|| is_float($argument)
|
||||
|| is_bool($argument)
|
||||
|| is_string($argument)
|
||||
|| $argument === null
|
||||
) {
|
||||
return new ReducedArgument($argument, get_debug_type($argument));
|
||||
}
|
||||
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
}
|
30
vendor/spatie/backtrace/src/Arguments/Reducers/ClosureArgumentReducer.php
vendored
Normal file
30
vendor/spatie/backtrace/src/Arguments/Reducers/ClosureArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Closure;
|
||||
use ReflectionFunction;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class ClosureArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof Closure) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
$reflection = new ReflectionFunction($argument);
|
||||
|
||||
if ($reflection->getFileName() && $reflection->getStartLine() && $reflection->getEndLine()) {
|
||||
return new ReducedArgument(
|
||||
"{$reflection->getFileName()}:{$reflection->getStartLine()}-{$reflection->getEndLine()}",
|
||||
'Closure'
|
||||
);
|
||||
}
|
||||
|
||||
return new ReducedArgument("{$reflection->getFileName()}", 'Closure');
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/Reducers/DateTimeArgumentReducer.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/Reducers/DateTimeArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class DateTimeArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof DateTimeInterface) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
$argument->format('d M Y H:i:s e'),
|
||||
get_class($argument),
|
||||
);
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/Reducers/DateTimeZoneArgumentReducer.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/Reducers/DateTimeZoneArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use DateTimeZone;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class DateTimeZoneArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof DateTimeZone) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
$argument->getName(),
|
||||
get_class($argument),
|
||||
);
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/Reducers/EnumArgumentReducer.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/Reducers/EnumArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
use UnitEnum;
|
||||
|
||||
class EnumArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof UnitEnum) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
get_class($argument).'::'.$argument->name,
|
||||
get_class($argument),
|
||||
);
|
||||
}
|
||||
}
|
22
vendor/spatie/backtrace/src/Arguments/Reducers/MinimalArrayArgumentReducer.php
vendored
Normal file
22
vendor/spatie/backtrace/src/Arguments/Reducers/MinimalArrayArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class MinimalArrayArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if(! is_array($argument)) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
'array (size='.count($argument).')',
|
||||
'array'
|
||||
);
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/Reducers/SensitiveParameterArrayReducer.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/Reducers/SensitiveParameterArrayReducer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use SensitiveParameterValue;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
|
||||
class SensitiveParameterArrayReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof SensitiveParameterValue) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
'SensitiveParameterValue('.get_debug_type($argument->getValue()).')',
|
||||
get_class($argument)
|
||||
);
|
||||
}
|
||||
}
|
19
vendor/spatie/backtrace/src/Arguments/Reducers/StdClassArgumentReducer.php
vendored
Normal file
19
vendor/spatie/backtrace/src/Arguments/Reducers/StdClassArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
use stdClass;
|
||||
|
||||
class StdClassArgumentReducer extends ArrayArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof stdClass) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return parent::reduceArgument((array) $argument, stdClass::class);
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/Reducers/StringableArgumentReducer.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/Reducers/StringableArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
use Stringable;
|
||||
|
||||
class StringableArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if (! $argument instanceof Stringable) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
(string) $argument,
|
||||
get_class($argument),
|
||||
);
|
||||
}
|
||||
}
|
23
vendor/spatie/backtrace/src/Arguments/Reducers/SymphonyRequestArgumentReducer.php
vendored
Normal file
23
vendor/spatie/backtrace/src/Arguments/Reducers/SymphonyRequestArgumentReducer.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace\Arguments\Reducers;
|
||||
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgument;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\ReducedArgumentContract;
|
||||
use Spatie\Backtrace\Arguments\ReducedArgument\UnReducedArgument;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class SymphonyRequestArgumentReducer implements ArgumentReducer
|
||||
{
|
||||
public function execute($argument): ReducedArgumentContract
|
||||
{
|
||||
if(! $argument instanceof Request) {
|
||||
return UnReducedArgument::create();
|
||||
}
|
||||
|
||||
return new ReducedArgument(
|
||||
"{$argument->getMethod()} {$argument->getUri()}",
|
||||
get_class($argument),
|
||||
);
|
||||
}
|
||||
}
|
271
vendor/spatie/backtrace/src/Backtrace.php
vendored
Normal file
271
vendor/spatie/backtrace/src/Backtrace.php
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
|
||||
use Closure;
|
||||
use Spatie\Backtrace\Arguments\ArgumentReducers;
|
||||
use Spatie\Backtrace\Arguments\ReduceArgumentsAction;
|
||||
use Spatie\Backtrace\Arguments\Reducers\ArgumentReducer;
|
||||
use Throwable;
|
||||
|
||||
class Backtrace
|
||||
{
|
||||
/** @var bool */
|
||||
protected $withArguments = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $reduceArguments = false;
|
||||
|
||||
/** @var array<class-string<ArgumentReducer>|ArgumentReducer>|ArgumentReducers|null */
|
||||
protected $argumentReducers = null;
|
||||
|
||||
/** @var bool */
|
||||
protected $withObject = false;
|
||||
|
||||
/** @var string|null */
|
||||
protected $applicationPath;
|
||||
|
||||
/** @var int */
|
||||
protected $offset = 0;
|
||||
|
||||
/** @var int */
|
||||
protected $limit = 0;
|
||||
|
||||
/** @var \Closure|null */
|
||||
protected $startingFromFrameClosure = null;
|
||||
|
||||
/** @var \Throwable|null */
|
||||
protected $throwable = null;
|
||||
|
||||
public static function create(): self
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
public static function createForThrowable(Throwable $throwable): self
|
||||
{
|
||||
return (new static())->forThrowable($throwable);
|
||||
}
|
||||
|
||||
protected function forThrowable(Throwable $throwable): self
|
||||
{
|
||||
$this->throwable = $throwable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withArguments(
|
||||
bool $withArguments = true
|
||||
): self {
|
||||
$this->withArguments = $withArguments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<class-string<ArgumentReducer>|ArgumentReducer>|ArgumentReducers|null $argumentReducers
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reduceArguments(
|
||||
$argumentReducers = null
|
||||
): self {
|
||||
$this->reduceArguments = true;
|
||||
$this->argumentReducers = $argumentReducers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withObject(): self
|
||||
{
|
||||
$this->withObject = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function applicationPath(string $applicationPath): self
|
||||
{
|
||||
$this->applicationPath = rtrim($applicationPath, '/');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offset(int $offset): self
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function limit(int $limit): self
|
||||
{
|
||||
$this->limit = $limit;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function startingFromFrame(Closure $startingFromFrameClosure)
|
||||
{
|
||||
$this->startingFromFrameClosure = $startingFromFrameClosure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Spatie\Backtrace\Frame[]
|
||||
*/
|
||||
public function frames(): array
|
||||
{
|
||||
$rawFrames = $this->getRawFrames();
|
||||
|
||||
return $this->toFrameObjects($rawFrames);
|
||||
}
|
||||
|
||||
public function firstApplicationFrameIndex(): ?int
|
||||
{
|
||||
foreach ($this->frames() as $index => $frame) {
|
||||
if ($frame->applicationFrame) {
|
||||
return $index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function getRawFrames(): array
|
||||
{
|
||||
if ($this->throwable) {
|
||||
return $this->throwable->getTrace();
|
||||
}
|
||||
|
||||
$options = null;
|
||||
|
||||
if (! $this->withArguments) {
|
||||
$options = $options | DEBUG_BACKTRACE_IGNORE_ARGS;
|
||||
}
|
||||
|
||||
if ($this->withObject()) {
|
||||
$options = $options | DEBUG_BACKTRACE_PROVIDE_OBJECT;
|
||||
}
|
||||
|
||||
$limit = $this->limit;
|
||||
|
||||
if ($limit !== 0) {
|
||||
$limit += 3;
|
||||
}
|
||||
|
||||
return debug_backtrace($options, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Spatie\Backtrace\Frame[]
|
||||
*/
|
||||
protected function toFrameObjects(array $rawFrames): array
|
||||
{
|
||||
$currentFile = $this->throwable ? $this->throwable->getFile() : '';
|
||||
$currentLine = $this->throwable ? $this->throwable->getLine() : 0;
|
||||
$arguments = $this->withArguments ? [] : null;
|
||||
|
||||
$frames = [];
|
||||
|
||||
$reduceArgumentsAction = new ReduceArgumentsAction($this->resolveArgumentReducers());
|
||||
|
||||
foreach ($rawFrames as $rawFrame) {
|
||||
$frames[] = new Frame(
|
||||
$currentFile,
|
||||
$currentLine,
|
||||
$arguments,
|
||||
$rawFrame['function'] ?? null,
|
||||
$rawFrame['class'] ?? null,
|
||||
$this->isApplicationFrame($currentFile)
|
||||
);
|
||||
|
||||
$arguments = $this->withArguments
|
||||
? $rawFrame['args'] ?? null
|
||||
: null;
|
||||
|
||||
if ($this->reduceArguments) {
|
||||
$arguments = $reduceArgumentsAction->execute(
|
||||
$rawFrame['class'] ?? null,
|
||||
$rawFrame['function'] ?? null,
|
||||
$arguments
|
||||
);
|
||||
}
|
||||
|
||||
$currentFile = $rawFrame['file'] ?? 'unknown';
|
||||
$currentLine = $rawFrame['line'] ?? 0;
|
||||
}
|
||||
|
||||
$frames[] = new Frame(
|
||||
$currentFile,
|
||||
$currentLine,
|
||||
[],
|
||||
'[top]'
|
||||
);
|
||||
|
||||
$frames = $this->removeBacktracePackageFrames($frames);
|
||||
|
||||
if ($closure = $this->startingFromFrameClosure) {
|
||||
$frames = $this->startAtFrameFromClosure($frames, $closure);
|
||||
}
|
||||
$frames = array_slice($frames, $this->offset, $this->limit === 0 ? PHP_INT_MAX : $this->limit);
|
||||
|
||||
return array_values($frames);
|
||||
}
|
||||
|
||||
protected function isApplicationFrame(string $frameFilename): bool
|
||||
{
|
||||
$relativeFile = str_replace('\\', DIRECTORY_SEPARATOR, $frameFilename);
|
||||
|
||||
if (! empty($this->applicationPath)) {
|
||||
$relativeFile = array_reverse(explode($this->applicationPath ?? '', $frameFilename, 2))[0];
|
||||
}
|
||||
|
||||
if (strpos($relativeFile, DIRECTORY_SEPARATOR.'vendor') === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function removeBacktracePackageFrames(array $frames): array
|
||||
{
|
||||
return $this->startAtFrameFromClosure($frames, function (Frame $frame) {
|
||||
return $frame->class !== static::class;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Spatie\Backtrace\Frame[] $frames
|
||||
* @param \Closure $closure
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function startAtFrameFromClosure(array $frames, Closure $closure): array
|
||||
{
|
||||
foreach ($frames as $i => $frame) {
|
||||
$foundStartingFrame = $closure($frame);
|
||||
|
||||
if ($foundStartingFrame) {
|
||||
return $frames;
|
||||
}
|
||||
|
||||
unset($frames[$i]);
|
||||
}
|
||||
|
||||
return $frames;
|
||||
}
|
||||
|
||||
protected function resolveArgumentReducers(): ArgumentReducers
|
||||
{
|
||||
if ($this->argumentReducers === null) {
|
||||
return ArgumentReducers::default();
|
||||
}
|
||||
|
||||
if ($this->argumentReducers instanceof ArgumentReducers) {
|
||||
return $this->argumentReducers;
|
||||
}
|
||||
|
||||
return ArgumentReducers::create($this->argumentReducers);
|
||||
}
|
||||
}
|
83
vendor/spatie/backtrace/src/CodeSnippet.php
vendored
Normal file
83
vendor/spatie/backtrace/src/CodeSnippet.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class CodeSnippet
|
||||
{
|
||||
/** @var int */
|
||||
protected $surroundingLine = 1;
|
||||
|
||||
/** @var int */
|
||||
protected $snippetLineCount = 9;
|
||||
|
||||
public function surroundingLine(int $surroundingLine): self
|
||||
{
|
||||
$this->surroundingLine = $surroundingLine;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function snippetLineCount(int $snippetLineCount): self
|
||||
{
|
||||
$this->snippetLineCount = $snippetLineCount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get(string $fileName): array
|
||||
{
|
||||
if (! file_exists($fileName)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$file = new File($fileName);
|
||||
|
||||
[$startLineNumber, $endLineNumber] = $this->getBounds($file->numberOfLines());
|
||||
|
||||
$code = [];
|
||||
|
||||
$line = $file->getLine($startLineNumber);
|
||||
|
||||
$currentLineNumber = $startLineNumber;
|
||||
|
||||
while ($currentLineNumber <= $endLineNumber) {
|
||||
$code[$currentLineNumber] = rtrim(substr($line, 0, 250));
|
||||
|
||||
$line = $file->getNextLine();
|
||||
$currentLineNumber++;
|
||||
}
|
||||
|
||||
return $code;
|
||||
} catch (RuntimeException $exception) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public function getAsString(string $fileName): string
|
||||
{
|
||||
$snippet = $this->get($fileName);
|
||||
|
||||
$snippetStrings = array_map(function (string $line, string $number) {
|
||||
return "{$number} {$line}";
|
||||
}, $snippet, array_keys($snippet));
|
||||
|
||||
return implode(PHP_EOL, $snippetStrings);
|
||||
}
|
||||
|
||||
protected function getBounds(int $totalNumberOfLineInFile): array
|
||||
{
|
||||
$startLine = max($this->surroundingLine - floor($this->snippetLineCount / 2), 1);
|
||||
|
||||
$endLine = $startLine + ($this->snippetLineCount - 1);
|
||||
|
||||
if ($endLine > $totalNumberOfLineInFile) {
|
||||
$endLine = $totalNumberOfLineInFile;
|
||||
$startLine = max($endLine - ($this->snippetLineCount - 1), 1);
|
||||
}
|
||||
|
||||
return [$startLine, $endLine];
|
||||
}
|
||||
}
|
41
vendor/spatie/backtrace/src/File.php
vendored
Normal file
41
vendor/spatie/backtrace/src/File.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
|
||||
use SplFileObject;
|
||||
|
||||
class File
|
||||
{
|
||||
/** @var \SplFileObject */
|
||||
protected $file;
|
||||
|
||||
public function __construct(string $path)
|
||||
{
|
||||
$this->file = new SplFileObject($path);
|
||||
}
|
||||
|
||||
public function numberOfLines(): int
|
||||
{
|
||||
$this->file->seek(PHP_INT_MAX);
|
||||
|
||||
return $this->file->key() + 1;
|
||||
}
|
||||
|
||||
public function getLine(int $lineNumber = null): string
|
||||
{
|
||||
if (is_null($lineNumber)) {
|
||||
return $this->getNextLine();
|
||||
}
|
||||
|
||||
$this->file->seek($lineNumber - 1);
|
||||
|
||||
return $this->file->current();
|
||||
}
|
||||
|
||||
public function getNextLine(): string
|
||||
{
|
||||
$this->file->next();
|
||||
|
||||
return $this->file->current();
|
||||
}
|
||||
}
|
73
vendor/spatie/backtrace/src/Frame.php
vendored
Normal file
73
vendor/spatie/backtrace/src/Frame.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Spatie\Backtrace;
|
||||
|
||||
class Frame
|
||||
{
|
||||
/** @var string */
|
||||
public $file;
|
||||
|
||||
/** @var int */
|
||||
public $lineNumber;
|
||||
|
||||
/** @var array|null */
|
||||
public $arguments = null;
|
||||
|
||||
/** @var bool */
|
||||
public $applicationFrame;
|
||||
|
||||
/** @var string|null */
|
||||
public $method;
|
||||
|
||||
/** @var string|null */
|
||||
public $class;
|
||||
|
||||
public function __construct(
|
||||
string $file,
|
||||
int $lineNumber,
|
||||
?array $arguments,
|
||||
string $method = null,
|
||||
string $class = null,
|
||||
bool $isApplicationFrame = false
|
||||
) {
|
||||
$this->file = $file;
|
||||
|
||||
$this->lineNumber = $lineNumber;
|
||||
|
||||
$this->arguments = $arguments;
|
||||
|
||||
$this->method = $method;
|
||||
|
||||
$this->class = $class;
|
||||
|
||||
$this->applicationFrame = $isApplicationFrame;
|
||||
}
|
||||
|
||||
public function getSnippet(int $lineCount): array
|
||||
{
|
||||
return (new CodeSnippet())
|
||||
->surroundingLine($this->lineNumber)
|
||||
->snippetLineCount($lineCount)
|
||||
->get($this->file);
|
||||
}
|
||||
|
||||
public function getSnippetAsString(int $lineCount): string
|
||||
{
|
||||
return (new CodeSnippet())
|
||||
->surroundingLine($this->lineNumber)
|
||||
->snippetLineCount($lineCount)
|
||||
->getAsString($this->file);
|
||||
}
|
||||
|
||||
public function getSnippetProperties(int $lineCount): array
|
||||
{
|
||||
$snippet = $this->getSnippet($lineCount);
|
||||
|
||||
return array_map(function (int $lineNumber) use ($snippet) {
|
||||
return [
|
||||
'line_number' => $lineNumber,
|
||||
'text' => $snippet[$lineNumber],
|
||||
];
|
||||
}, array_keys($snippet));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user