laravel-6 support
This commit is contained in:
1
vendor/facade/flare-client-php/.php-cs-fixer.cache
vendored
Normal file
1
vendor/facade/flare-client-php/.php-cs-fixer.cache
vendored
Normal file
File diff suppressed because one or more lines are too long
44
vendor/facade/flare-client-php/.php-cs-fixer.php
vendored
Normal file
44
vendor/facade/flare-client-php/.php-cs-fixer.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
$finder = Symfony\Component\Finder\Finder::create()
|
||||
->notPath('bootstrap/*')
|
||||
->notPath('storage/*')
|
||||
->notPath('resources/view/mail/*')
|
||||
->in([
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
])
|
||||
->name('*.php')
|
||||
->notName('*.blade.php')
|
||||
->notName('GitConflictController.php')
|
||||
->ignoreDotFiles(true)
|
||||
->ignoreVCS(true);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRules([
|
||||
'@PSR12' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'ordered_imports' => ['sort_algorithm' => 'alpha'],
|
||||
'no_unused_imports' => true,
|
||||
'not_operator_with_successor_space' => true,
|
||||
'trailing_comma_in_multiline' => true,
|
||||
'phpdoc_scalar' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'binary_operator_spaces' => true,
|
||||
'blank_line_before_statement' => [
|
||||
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
|
||||
],
|
||||
'phpdoc_single_line_var_spacing' => true,
|
||||
'phpdoc_var_without_name' => true,
|
||||
'class_attributes_separation' => [
|
||||
'elements' => [
|
||||
'method' => 'one',
|
||||
],
|
||||
],
|
||||
'method_argument_space' => [
|
||||
'on_multiline' => 'ensure_fully_multiline',
|
||||
'keep_multiple_spaces_after_comma' => true,
|
||||
],
|
||||
'single_trait_insert_per_statement' => true,
|
||||
])
|
||||
->setFinder($finder);
|
||||
114
vendor/facade/flare-client-php/CHANGELOG.md
vendored
Normal file
114
vendor/facade/flare-client-php/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to `flare-client-php` will be documented in this file
|
||||
|
||||
## 1.9.1 - 2021-09-13
|
||||
|
||||
- let `report` return the created report
|
||||
|
||||
## 1.9.0 - 2021-09-13
|
||||
|
||||
- add report tracking uuid
|
||||
|
||||
## 1.8.1 - 2021-05-31
|
||||
|
||||
- improve compatibility with Symfony 5.3
|
||||
|
||||
## 1.8.0 - 2021-04-30
|
||||
|
||||
- add ability to ignore errors and exceptions (#23)
|
||||
- fix curl parameters
|
||||
|
||||
## 1.7.0 - 2021-04-12
|
||||
|
||||
- use new Flare endpoint and allow 1 redirect to it
|
||||
|
||||
## 1.6.1 - 2021-04-08
|
||||
|
||||
- make `censorRequestBodyFields` chainable
|
||||
|
||||
## 1.6.0 - 2021-04-08
|
||||
|
||||
- add ability to censor request body fields (#18)
|
||||
|
||||
## 1.5.0 - 2021-03-31
|
||||
|
||||
- add `determineVersionUsing`
|
||||
|
||||
## 1.4.0 - 2021-02-16
|
||||
|
||||
- remove custom grouping
|
||||
|
||||
## 1.3.7 - 2020-10-21
|
||||
|
||||
- allow PHP 8
|
||||
|
||||
## 1.3.6 - 2020-09-18
|
||||
|
||||
- remove `larapack/dd` (#15)
|
||||
|
||||
## 1.3.5 - 2020-08-26
|
||||
|
||||
- allow Laravel 8 (#13)
|
||||
|
||||
## 1.3.4 - 2020-07-14
|
||||
|
||||
- use directory separator constant
|
||||
|
||||
## 1.3.3 - 2020-07-14
|
||||
|
||||
- fix tests by requiring symfony/mime
|
||||
- display real exception class for view errors (see https://github.com/facade/ignition/discussions/237)
|
||||
|
||||
## 1.3.2 - 2020-03-02
|
||||
|
||||
- allow L7
|
||||
|
||||
## 1.3.1 - 2019-12-15
|
||||
|
||||
- allow var-dumper v5.0
|
||||
|
||||
## 1.3.0 - 2019-11-27
|
||||
|
||||
- Allow custom grouping types
|
||||
|
||||
## 1.2.1 - 2019-11-19
|
||||
|
||||
- Let `registerFlareHandlers` return $this
|
||||
|
||||
## 1.2.0 - 2019-11-19
|
||||
|
||||
- Add `registerFlareHandlers` method to register error and exception handlers in non-Laravel applications
|
||||
- Fix get requests with query parameters (#4)
|
||||
|
||||
## 1.1.2 - 2019-11-08
|
||||
|
||||
- Ignore invalid mime type detection issues
|
||||
|
||||
## 1.1.1 - 2019-10-07
|
||||
|
||||
- Wrap filesize detection in try-catch block
|
||||
|
||||
## 1.1.0 - 2019-09-27
|
||||
|
||||
- Add ability to log messages
|
||||
|
||||
## 1.0.4 - 2019-09-11
|
||||
|
||||
- Fixes an issue when sending exceptions inside a queue worker
|
||||
|
||||
## 1.0.3 - 2019-09-05
|
||||
|
||||
- Ensure valid session data
|
||||
|
||||
## 1.0.2 - 2019-09-05
|
||||
|
||||
- Fix error when uploading multiple files using an array name
|
||||
|
||||
## 1.0.1 - 2019-09-02
|
||||
|
||||
- Fix issue with uploaded files in request context
|
||||
|
||||
## 1.0.0 - 2019-08-30
|
||||
|
||||
- initial release
|
||||
21
vendor/facade/flare-client-php/LICENSE.md
vendored
Normal file
21
vendor/facade/flare-client-php/LICENSE.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Facade <info@facade.company>
|
||||
|
||||
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.
|
||||
36
vendor/facade/flare-client-php/README.md
vendored
Normal file
36
vendor/facade/flare-client-php/README.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Send PHP errors to Flare
|
||||
|
||||
[](https://packagist.org/packages/facade/flare-client-php)
|
||||

|
||||
[](https://packagist.org/packages/facade/flare-client-php)
|
||||
|
||||
This repository contains a PHP client to send PHP errors to [Flare](https://flareapp.io).
|
||||
|
||||

|
||||
|
||||
## Documentation
|
||||
|
||||
You can find the documentation of this package at [the docs of Flare](https://flareapp.io/docs/general/projects).
|
||||
|
||||
## Changelog
|
||||
|
||||
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
|
||||
|
||||
## Testing
|
||||
|
||||
``` bash
|
||||
composer test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
|
||||
|
||||
## Security
|
||||
|
||||
If you discover any security related issues, please email support@flareapp.io instead of using the issue tracker.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
||||
|
||||
52
vendor/facade/flare-client-php/composer.json
vendored
Normal file
52
vendor/facade/flare-client-php/composer.json
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "facade/flare-client-php",
|
||||
"description": "Send PHP errors to Flare",
|
||||
"keywords": [
|
||||
"facade",
|
||||
"flare",
|
||||
"exception",
|
||||
"reporting"
|
||||
],
|
||||
"homepage": "https://github.com/facade/flare-client-php",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.1|^8.0",
|
||||
"facade/ignition-contracts": "~1.0",
|
||||
"illuminate/pipeline": "^5.5|^6.0|^7.0|^8.0",
|
||||
"symfony/http-foundation": "^3.3|^4.1|^5.0",
|
||||
"symfony/mime": "^3.4|^4.0|^5.1",
|
||||
"symfony/var-dumper": "^3.4|^4.0|^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"spatie/phpunit-snapshot-assertions": "^2.0",
|
||||
"phpunit/phpunit": "^7.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\FlareClient\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Facade\\FlareClient\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes",
|
||||
"test": "vendor/bin/phpunit",
|
||||
"test-coverage": "vendor/bin/phpunit --coverage-html coverage"
|
||||
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
77
vendor/facade/flare-client-php/src/Api.php
vendored
Normal file
77
vendor/facade/flare-client-php/src/Api.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient;
|
||||
|
||||
use Exception;
|
||||
use Facade\FlareClient\Http\Client;
|
||||
use Facade\FlareClient\Truncation\ReportTrimmer;
|
||||
|
||||
class Api
|
||||
{
|
||||
/** @var \Facade\FlareClient\Http\Client */
|
||||
protected $client;
|
||||
|
||||
/** @var bool */
|
||||
public static $sendInBatches = true;
|
||||
|
||||
/** @var array */
|
||||
protected $queue = [];
|
||||
|
||||
public function __construct(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
|
||||
register_shutdown_function([$this, 'sendQueuedReports']);
|
||||
}
|
||||
|
||||
public static function sendReportsInBatches(bool $batchSending = true)
|
||||
{
|
||||
static::$sendInBatches = $batchSending;
|
||||
}
|
||||
|
||||
public function report(Report $report)
|
||||
{
|
||||
try {
|
||||
if (static::$sendInBatches) {
|
||||
$this->addReportToQueue($report);
|
||||
} else {
|
||||
$this->sendReportToApi($report);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
public function sendTestReport(Report $report)
|
||||
{
|
||||
$this->sendReportToApi($report);
|
||||
}
|
||||
|
||||
protected function addReportToQueue(Report $report)
|
||||
{
|
||||
$this->queue[] = $report;
|
||||
}
|
||||
|
||||
public function sendQueuedReports()
|
||||
{
|
||||
try {
|
||||
foreach ($this->queue as $report) {
|
||||
$this->sendReportToApi($report);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
//
|
||||
} finally {
|
||||
$this->queue = [];
|
||||
}
|
||||
}
|
||||
|
||||
protected function sendReportToApi(Report $report)
|
||||
{
|
||||
$this->client->post('reports', $this->truncateReport($report->toArray()));
|
||||
}
|
||||
|
||||
protected function truncateReport(array $payload): array
|
||||
{
|
||||
return (new ReportTrimmer())->trim($payload);
|
||||
}
|
||||
}
|
||||
51
vendor/facade/flare-client-php/src/Concerns/HasContext.php
vendored
Normal file
51
vendor/facade/flare-client-php/src/Concerns/HasContext.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Concerns;
|
||||
|
||||
trait HasContext
|
||||
{
|
||||
/** @var string|null */
|
||||
private $messageLevel;
|
||||
|
||||
/** @var string|null */
|
||||
private $stage;
|
||||
|
||||
/** @var array */
|
||||
private $userProvidedContext = [];
|
||||
|
||||
public function stage(?string $stage)
|
||||
{
|
||||
$this->stage = $stage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function messageLevel(?string $messageLevel)
|
||||
{
|
||||
$this->messageLevel = $messageLevel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getGroup(string $groupName = 'context', $default = []): array
|
||||
{
|
||||
return $this->userProvidedContext[$groupName] ?? $default;
|
||||
}
|
||||
|
||||
public function context($key, $value)
|
||||
{
|
||||
return $this->group('context', [$key => $value]);
|
||||
}
|
||||
|
||||
public function group(string $groupName, array $properties)
|
||||
{
|
||||
$group = $this->userProvidedContext[$groupName] ?? [];
|
||||
|
||||
$this->userProvidedContext[$groupName] = array_merge_recursive_distinct(
|
||||
$group,
|
||||
$properties
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
24
vendor/facade/flare-client-php/src/Concerns/UsesTime.php
vendored
Normal file
24
vendor/facade/flare-client-php/src/Concerns/UsesTime.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Concerns;
|
||||
|
||||
use Facade\FlareClient\Time\SystemTime;
|
||||
use Facade\FlareClient\Time\Time;
|
||||
|
||||
trait UsesTime
|
||||
{
|
||||
/** @var \Facade\FlareClient\Time\Time */
|
||||
public static $time;
|
||||
|
||||
public static function useTime(Time $time)
|
||||
{
|
||||
self::$time = $time;
|
||||
}
|
||||
|
||||
public function getCurrentTime(): int
|
||||
{
|
||||
$time = self::$time ?? new SystemTime();
|
||||
|
||||
return $time->getCurrentTime();
|
||||
}
|
||||
}
|
||||
21
vendor/facade/flare-client-php/src/Context/ConsoleContext.php
vendored
Normal file
21
vendor/facade/flare-client-php/src/Context/ConsoleContext.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Context;
|
||||
|
||||
class ConsoleContext implements ContextInterface
|
||||
{
|
||||
/** @var array */
|
||||
private $arguments = [];
|
||||
|
||||
public function __construct(array $arguments = [])
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'arguments' => $this->arguments,
|
||||
];
|
||||
}
|
||||
}
|
||||
28
vendor/facade/flare-client-php/src/Context/ContextContextDetector.php
vendored
Normal file
28
vendor/facade/flare-client-php/src/Context/ContextContextDetector.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Context;
|
||||
|
||||
class ContextContextDetector implements ContextDetectorInterface
|
||||
{
|
||||
public function detectCurrentContext(): ContextInterface
|
||||
{
|
||||
if ($this->runningInConsole()) {
|
||||
return new ConsoleContext($_SERVER['argv'] ?? []);
|
||||
}
|
||||
|
||||
return new RequestContext();
|
||||
}
|
||||
|
||||
private function runningInConsole(): bool
|
||||
{
|
||||
if (isset($_ENV['APP_RUNNING_IN_CONSOLE'])) {
|
||||
return $_ENV['APP_RUNNING_IN_CONSOLE'] === 'true';
|
||||
}
|
||||
|
||||
if (isset($_ENV['FLARE_FAKE_WEB_REQUEST'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array(php_sapi_name(), ['cli', 'phpdb']);
|
||||
}
|
||||
}
|
||||
8
vendor/facade/flare-client-php/src/Context/ContextDetectorInterface.php
vendored
Normal file
8
vendor/facade/flare-client-php/src/Context/ContextDetectorInterface.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Context;
|
||||
|
||||
interface ContextDetectorInterface
|
||||
{
|
||||
public function detectCurrentContext(): ContextInterface;
|
||||
}
|
||||
8
vendor/facade/flare-client-php/src/Context/ContextInterface.php
vendored
Normal file
8
vendor/facade/flare-client-php/src/Context/ContextInterface.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Context;
|
||||
|
||||
interface ContextInterface
|
||||
{
|
||||
public function toArray(): array;
|
||||
}
|
||||
126
vendor/facade/flare-client-php/src/Context/RequestContext.php
vendored
Normal file
126
vendor/facade/flare-client-php/src/Context/RequestContext.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Context;
|
||||
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Mime\Exception\InvalidArgumentException;
|
||||
use Throwable;
|
||||
|
||||
class RequestContext implements ContextInterface
|
||||
{
|
||||
/** @var \Symfony\Component\HttpFoundation\Request|null */
|
||||
protected $request;
|
||||
|
||||
public function __construct(Request $request = null)
|
||||
{
|
||||
$this->request = $request ?? Request::createFromGlobals();
|
||||
}
|
||||
|
||||
public function getRequest(): array
|
||||
{
|
||||
return [
|
||||
'url' => $this->request->getUri(),
|
||||
'ip' => $this->request->getClientIp(),
|
||||
'method' => $this->request->getMethod(),
|
||||
'useragent' => $this->request->headers->get('User-Agent'),
|
||||
];
|
||||
}
|
||||
|
||||
private function getFiles(): array
|
||||
{
|
||||
if (is_null($this->request->files)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->mapFiles($this->request->files->all());
|
||||
}
|
||||
|
||||
protected function mapFiles(array $files)
|
||||
{
|
||||
return array_map(function ($file) {
|
||||
if (is_array($file)) {
|
||||
return $this->mapFiles($file);
|
||||
}
|
||||
|
||||
if (! $file instanceof UploadedFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$fileSize = $file->getSize();
|
||||
} catch (\RuntimeException $e) {
|
||||
$fileSize = 0;
|
||||
}
|
||||
|
||||
try {
|
||||
$mimeType = $file->getMimeType();
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$mimeType = 'undefined';
|
||||
}
|
||||
|
||||
return [
|
||||
'pathname' => $file->getPathname(),
|
||||
'size' => $fileSize,
|
||||
'mimeType' => $mimeType,
|
||||
];
|
||||
}, $files);
|
||||
}
|
||||
|
||||
public function getSession(): array
|
||||
{
|
||||
try {
|
||||
$session = $this->request->getSession();
|
||||
} catch (\Exception $exception) {
|
||||
$session = [];
|
||||
}
|
||||
|
||||
return $session ? $this->getValidSessionData($session) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SessionInterface $session
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidSessionData($session): array
|
||||
{
|
||||
try {
|
||||
json_encode($session->all());
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $session->all();
|
||||
}
|
||||
|
||||
public function getCookies(): array
|
||||
{
|
||||
return $this->request->cookies->all();
|
||||
}
|
||||
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->request->headers->all();
|
||||
}
|
||||
|
||||
public function getRequestData(): array
|
||||
{
|
||||
return [
|
||||
'queryString' => $this->request->query->all(),
|
||||
'body' => $this->request->request->all(),
|
||||
'files' => $this->getFiles(),
|
||||
];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'request' => $this->getRequest(),
|
||||
'request_data' => $this->getRequestData(),
|
||||
'headers' => $this->getHeaders(),
|
||||
'cookies' => $this->getCookies(),
|
||||
'session' => $this->getSession(),
|
||||
];
|
||||
}
|
||||
}
|
||||
8
vendor/facade/flare-client-php/src/Contracts/ProvidesFlareContext.php
vendored
Normal file
8
vendor/facade/flare-client-php/src/Contracts/ProvidesFlareContext.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Contracts;
|
||||
|
||||
interface ProvidesFlareContext
|
||||
{
|
||||
public function context(): array;
|
||||
}
|
||||
11
vendor/facade/flare-client-php/src/Enums/GroupingTypes.php
vendored
Normal file
11
vendor/facade/flare-client-php/src/Enums/GroupingTypes.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Enums;
|
||||
|
||||
/** @deprecated */
|
||||
class GroupingTypes
|
||||
{
|
||||
public const TOP_FRAME = 'topFrame';
|
||||
|
||||
public const EXCEPTION = 'exceptionClass';
|
||||
}
|
||||
16
vendor/facade/flare-client-php/src/Enums/MessageLevels.php
vendored
Normal file
16
vendor/facade/flare-client-php/src/Enums/MessageLevels.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Enums;
|
||||
|
||||
class MessageLevels
|
||||
{
|
||||
public const INFO = 'info';
|
||||
|
||||
public const DEBUG = 'debug';
|
||||
|
||||
public const WARNING = 'warning';
|
||||
|
||||
public const ERROR = 'error';
|
||||
|
||||
public const CRITICAL = 'critical';
|
||||
}
|
||||
333
vendor/facade/flare-client-php/src/Flare.php
vendored
Executable file
333
vendor/facade/flare-client-php/src/Flare.php
vendored
Executable file
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient;
|
||||
|
||||
use Error;
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use Facade\FlareClient\Concerns\HasContext;
|
||||
use Facade\FlareClient\Context\ContextContextDetector;
|
||||
use Facade\FlareClient\Context\ContextDetectorInterface;
|
||||
use Facade\FlareClient\Enums\MessageLevels;
|
||||
use Facade\FlareClient\Glows\Glow;
|
||||
use Facade\FlareClient\Glows\Recorder;
|
||||
use Facade\FlareClient\Http\Client;
|
||||
use Facade\FlareClient\Middleware\AddGlows;
|
||||
use Facade\FlareClient\Middleware\AnonymizeIp;
|
||||
use Facade\FlareClient\Middleware\CensorRequestBodyFields;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Pipeline\Pipeline;
|
||||
use Throwable;
|
||||
|
||||
class Flare
|
||||
{
|
||||
use HasContext;
|
||||
|
||||
/** @var \Facade\FlareClient\Http\Client */
|
||||
protected $client;
|
||||
|
||||
/** @var \Facade\FlareClient\Api */
|
||||
protected $api;
|
||||
|
||||
/** @var array */
|
||||
protected $middleware = [];
|
||||
|
||||
/** @var \Facade\FlareClient\Glows\Recorder */
|
||||
protected $recorder;
|
||||
|
||||
/** @var string */
|
||||
protected $applicationPath;
|
||||
|
||||
/** @var \Illuminate\Contracts\Container\Container|null */
|
||||
protected $container;
|
||||
|
||||
/** @var ContextDetectorInterface */
|
||||
protected $contextDetector;
|
||||
|
||||
/** @var callable|null */
|
||||
protected $previousExceptionHandler;
|
||||
|
||||
/** @var callable|null */
|
||||
protected $previousErrorHandler;
|
||||
|
||||
/** @var callable|null */
|
||||
protected $determineVersionCallable;
|
||||
|
||||
/** @var int|null */
|
||||
protected $reportErrorLevels;
|
||||
|
||||
/** @var callable|null */
|
||||
protected $filterExceptionsCallable;
|
||||
|
||||
/** @var callable|null */
|
||||
protected $filterReportsCallable;
|
||||
|
||||
public static function register(string $apiKey, string $apiSecret = null, ContextDetectorInterface $contextDetector = null, Container $container = null)
|
||||
{
|
||||
$client = new Client($apiKey, $apiSecret);
|
||||
|
||||
return new static($client, $contextDetector, $container);
|
||||
}
|
||||
|
||||
public function determineVersionUsing($determineVersionCallable)
|
||||
{
|
||||
$this->determineVersionCallable = $determineVersionCallable;
|
||||
}
|
||||
|
||||
public function reportErrorLevels(int $reportErrorLevels)
|
||||
{
|
||||
$this->reportErrorLevels = $reportErrorLevels;
|
||||
}
|
||||
|
||||
public function filterExceptionsUsing(callable $filterExceptionsCallable)
|
||||
{
|
||||
$this->filterExceptionsCallable = $filterExceptionsCallable;
|
||||
}
|
||||
|
||||
public function filterReportsUsing(callable $filterReportsCallable)
|
||||
{
|
||||
$this->filterReportsCallable = $filterReportsCallable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function version()
|
||||
{
|
||||
if (! $this->determineVersionCallable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ($this->determineVersionCallable)();
|
||||
}
|
||||
|
||||
public function __construct(Client $client, ContextDetectorInterface $contextDetector = null, Container $container = null, array $middleware = [])
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->recorder = new Recorder();
|
||||
$this->contextDetector = $contextDetector ?? new ContextContextDetector();
|
||||
$this->container = $container;
|
||||
$this->middleware = $middleware;
|
||||
$this->api = new Api($this->client);
|
||||
|
||||
$this->registerDefaultMiddleware();
|
||||
}
|
||||
|
||||
public function getMiddleware(): array
|
||||
{
|
||||
return $this->middleware;
|
||||
}
|
||||
|
||||
public function registerFlareHandlers()
|
||||
{
|
||||
$this->registerExceptionHandler();
|
||||
$this->registerErrorHandler();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function registerExceptionHandler()
|
||||
{
|
||||
$this->previousExceptionHandler = set_exception_handler([$this, 'handleException']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function registerErrorHandler()
|
||||
{
|
||||
$this->previousErrorHandler = set_error_handler([$this, 'handleError']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function registerDefaultMiddleware()
|
||||
{
|
||||
return $this->registerMiddleware(new AddGlows($this->recorder));
|
||||
}
|
||||
|
||||
public function registerMiddleware($callable)
|
||||
{
|
||||
$this->middleware[] = $callable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMiddlewares(): array
|
||||
{
|
||||
return $this->middleware;
|
||||
}
|
||||
|
||||
public function glow(
|
||||
string $name,
|
||||
string $messageLevel = MessageLevels::INFO,
|
||||
array $metaData = []
|
||||
) {
|
||||
$this->recorder->record(new Glow($name, $messageLevel, $metaData));
|
||||
}
|
||||
|
||||
public function handleException(Throwable $throwable)
|
||||
{
|
||||
$this->report($throwable);
|
||||
|
||||
if ($this->previousExceptionHandler) {
|
||||
call_user_func($this->previousExceptionHandler, $throwable);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleError($code, $message, $file = '', $line = 0)
|
||||
{
|
||||
$exception = new ErrorException($message, 0, $code, $file, $line);
|
||||
|
||||
$this->report($exception);
|
||||
|
||||
if ($this->previousErrorHandler) {
|
||||
return call_user_func(
|
||||
$this->previousErrorHandler,
|
||||
$message,
|
||||
$code,
|
||||
$file,
|
||||
$line
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function applicationPath(string $applicationPath)
|
||||
{
|
||||
$this->applicationPath = $applicationPath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function report(Throwable $throwable, callable $callback = null): ?Report
|
||||
{
|
||||
if (! $this->shouldSendReport($throwable)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$report = $this->createReport($throwable);
|
||||
|
||||
if (! is_null($callback)) {
|
||||
call_user_func($callback, $report);
|
||||
}
|
||||
|
||||
$this->sendReportToApi($report);
|
||||
|
||||
return $report;
|
||||
}
|
||||
|
||||
protected function shouldSendReport(Throwable $throwable): bool
|
||||
{
|
||||
if ($this->reportErrorLevels && $throwable instanceof Error) {
|
||||
return $this->reportErrorLevels & $throwable->getCode();
|
||||
}
|
||||
|
||||
if ($this->reportErrorLevels && $throwable instanceof ErrorException) {
|
||||
return $this->reportErrorLevels & $throwable->getSeverity();
|
||||
}
|
||||
|
||||
if ($this->filterExceptionsCallable && $throwable instanceof Exception) {
|
||||
return call_user_func($this->filterExceptionsCallable, $throwable);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function reportMessage(string $message, string $logLevel, callable $callback = null)
|
||||
{
|
||||
$report = $this->createReportFromMessage($message, $logLevel);
|
||||
|
||||
if (! is_null($callback)) {
|
||||
call_user_func($callback, $report);
|
||||
}
|
||||
|
||||
$this->sendReportToApi($report);
|
||||
}
|
||||
|
||||
public function sendTestReport(Throwable $throwable)
|
||||
{
|
||||
$this->api->sendTestReport($this->createReport($throwable));
|
||||
}
|
||||
|
||||
private function sendReportToApi(Report $report)
|
||||
{
|
||||
if ($this->filterReportsCallable) {
|
||||
if (! call_user_func($this->filterReportsCallable, $report)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->api->report($report);
|
||||
} catch (Exception $exception) {
|
||||
}
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->api->sendQueuedReports();
|
||||
|
||||
$this->userProvidedContext = [];
|
||||
$this->recorder->reset();
|
||||
}
|
||||
|
||||
private function applyAdditionalParameters(Report $report)
|
||||
{
|
||||
$report
|
||||
->stage($this->stage)
|
||||
->messageLevel($this->messageLevel)
|
||||
->setApplicationPath($this->applicationPath)
|
||||
->userProvidedContext($this->userProvidedContext);
|
||||
}
|
||||
|
||||
public function anonymizeIp()
|
||||
{
|
||||
$this->registerMiddleware(new AnonymizeIp());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function censorRequestBodyFields(array $fieldNames)
|
||||
{
|
||||
$this->registerMiddleware(new CensorRequestBodyFields($fieldNames));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function createReport(Throwable $throwable): Report
|
||||
{
|
||||
$report = Report::createForThrowable(
|
||||
$throwable,
|
||||
$this->contextDetector->detectCurrentContext(),
|
||||
$this->applicationPath,
|
||||
$this->version()
|
||||
);
|
||||
|
||||
return $this->applyMiddlewareToReport($report);
|
||||
}
|
||||
|
||||
public function createReportFromMessage(string $message, string $logLevel): Report
|
||||
{
|
||||
$report = Report::createForMessage(
|
||||
$message,
|
||||
$logLevel,
|
||||
$this->contextDetector->detectCurrentContext(),
|
||||
$this->applicationPath
|
||||
);
|
||||
|
||||
return $this->applyMiddlewareToReport($report);
|
||||
}
|
||||
|
||||
protected function applyMiddlewareToReport(Report $report): Report
|
||||
{
|
||||
$this->applyAdditionalParameters($report);
|
||||
|
||||
$report = (new Pipeline($this->container))
|
||||
->send($report)
|
||||
->through($this->middleware)
|
||||
->then(function ($report) {
|
||||
return $report;
|
||||
});
|
||||
|
||||
return $report;
|
||||
}
|
||||
}
|
||||
66
vendor/facade/flare-client-php/src/Frame.php
vendored
Normal file
66
vendor/facade/flare-client-php/src/Frame.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient;
|
||||
|
||||
use Facade\FlareClient\Stacktrace\Codesnippet;
|
||||
|
||||
class Frame
|
||||
{
|
||||
/** @var string */
|
||||
protected $file;
|
||||
|
||||
/** @var int */
|
||||
protected $lineNumber;
|
||||
|
||||
/** @var string */
|
||||
protected $method;
|
||||
|
||||
/** @var string */
|
||||
protected $class;
|
||||
|
||||
public function __construct(
|
||||
string $file,
|
||||
int $lineNumber,
|
||||
string $method = null,
|
||||
string $class = null
|
||||
) {
|
||||
$this->file = $file;
|
||||
|
||||
$this->lineNumber = $lineNumber;
|
||||
|
||||
$this->method = $method;
|
||||
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$codeSnippet = (new Codesnippet())
|
||||
->snippetLineCount(9)
|
||||
->surroundingLine($this->lineNumber)
|
||||
->get($this->file);
|
||||
|
||||
return [
|
||||
'line_number' => $this->lineNumber,
|
||||
'method' => $this->getFullMethod(),
|
||||
'code_snippet' => $codeSnippet,
|
||||
'file' => $this->file,
|
||||
];
|
||||
}
|
||||
|
||||
private function getFullMethod(): string
|
||||
{
|
||||
$method = $this->method;
|
||||
|
||||
if ($class = $this->class ?? false) {
|
||||
$method = "{$class}::{$method}";
|
||||
}
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
public function getFile(): string
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
}
|
||||
42
vendor/facade/flare-client-php/src/Glows/Glow.php
vendored
Normal file
42
vendor/facade/flare-client-php/src/Glows/Glow.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Glows;
|
||||
|
||||
use Facade\FlareClient\Concerns\UsesTime;
|
||||
use Facade\FlareClient\Enums\MessageLevels;
|
||||
|
||||
class Glow
|
||||
{
|
||||
use UsesTime;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var array */
|
||||
private $metaData;
|
||||
|
||||
/** @var string */
|
||||
private $messageLevel;
|
||||
|
||||
/** @var float */
|
||||
private $microtime;
|
||||
|
||||
public function __construct(string $name, string $messageLevel = MessageLevels::INFO, array $metaData = [], ?float $microtime = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->messageLevel = $messageLevel;
|
||||
$this->metaData = $metaData;
|
||||
$this->microtime = $microtime ?? microtime(true);
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'time' => $this->getCurrentTime(),
|
||||
'name' => $this->name,
|
||||
'message_level' => $this->messageLevel,
|
||||
'meta_data' => $this->metaData,
|
||||
'microtime' => $this->microtime,
|
||||
];
|
||||
}
|
||||
}
|
||||
27
vendor/facade/flare-client-php/src/Glows/Recorder.php
vendored
Normal file
27
vendor/facade/flare-client-php/src/Glows/Recorder.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Glows;
|
||||
|
||||
class Recorder
|
||||
{
|
||||
public const GLOW_LIMIT = 30;
|
||||
|
||||
private $glows = [];
|
||||
|
||||
public function record(Glow $glow)
|
||||
{
|
||||
$this->glows[] = $glow;
|
||||
|
||||
$this->glows = array_slice($this->glows, static::GLOW_LIMIT * -1, static::GLOW_LIMIT);
|
||||
}
|
||||
|
||||
public function glows(): array
|
||||
{
|
||||
return $this->glows;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->glows = [];
|
||||
}
|
||||
}
|
||||
217
vendor/facade/flare-client-php/src/Http/Client.php
vendored
Normal file
217
vendor/facade/flare-client-php/src/Http/Client.php
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http;
|
||||
|
||||
use Facade\FlareClient\Http\Exceptions\BadResponseCode;
|
||||
use Facade\FlareClient\Http\Exceptions\InvalidData;
|
||||
use Facade\FlareClient\Http\Exceptions\MissingParameter;
|
||||
use Facade\FlareClient\Http\Exceptions\NotFound;
|
||||
|
||||
class Client
|
||||
{
|
||||
/** @var null|string */
|
||||
private $apiToken;
|
||||
|
||||
/** @var null|string */
|
||||
private $apiSecret;
|
||||
|
||||
/** @var string */
|
||||
private $baseUrl;
|
||||
|
||||
/** @var int */
|
||||
private $timeout;
|
||||
|
||||
public function __construct(
|
||||
?string $apiToken,
|
||||
?string $apiSecret,
|
||||
string $baseUrl = 'https://reporting.flareapp.io/api',
|
||||
int $timeout = 10
|
||||
) {
|
||||
$this->apiToken = $apiToken;
|
||||
|
||||
$this->apiSecret = $apiSecret;
|
||||
|
||||
if (! $baseUrl) {
|
||||
throw MissingParameter::create('baseUrl');
|
||||
}
|
||||
|
||||
$this->baseUrl = $baseUrl;
|
||||
|
||||
if (! $timeout) {
|
||||
throw MissingParameter::create('timeout');
|
||||
}
|
||||
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function get(string $url, array $arguments = [])
|
||||
{
|
||||
return $this->makeRequest('get', $url, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function post(string $url, array $arguments = [])
|
||||
{
|
||||
return $this->makeRequest('post', $url, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function patch(string $url, array $arguments = [])
|
||||
{
|
||||
return $this->makeRequest('patch', $url, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function put(string $url, array $arguments = [])
|
||||
{
|
||||
return $this->makeRequest('put', $url, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function delete(string $method, array $arguments = [])
|
||||
{
|
||||
return $this->makeRequest('delete', $method, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $httpVerb
|
||||
* @param string $url
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function makeRequest(string $httpVerb, string $url, array $arguments = [])
|
||||
{
|
||||
$queryString = http_build_query([
|
||||
'key' => $this->apiToken,
|
||||
'secret' => $this->apiSecret,
|
||||
]);
|
||||
|
||||
$fullUrl = "{$this->baseUrl}/{$url}?{$queryString}";
|
||||
|
||||
$headers = [
|
||||
'x-api-token: '.$this->apiToken,
|
||||
];
|
||||
|
||||
$response = $this->makeCurlRequest($httpVerb, $fullUrl, $headers, $arguments);
|
||||
|
||||
if ($response->getHttpResponseCode() === 422) {
|
||||
throw InvalidData::createForResponse($response);
|
||||
}
|
||||
|
||||
if ($response->getHttpResponseCode() === 404) {
|
||||
throw NotFound::createForResponse($response);
|
||||
}
|
||||
|
||||
if ($response->getHttpResponseCode() !== 200 && $response->getHttpResponseCode() !== 204) {
|
||||
throw BadResponseCode::createForResponse($response);
|
||||
}
|
||||
|
||||
return $response->getBody();
|
||||
}
|
||||
|
||||
public function makeCurlRequest(string $httpVerb, string $fullUrl, array $headers = [], array $arguments = []): Response
|
||||
{
|
||||
$curlHandle = $this->getCurlHandle($fullUrl, $headers);
|
||||
|
||||
switch ($httpVerb) {
|
||||
case 'post':
|
||||
curl_setopt($curlHandle, CURLOPT_POST, true);
|
||||
$this->attachRequestPayload($curlHandle, $arguments);
|
||||
|
||||
break;
|
||||
|
||||
case 'get':
|
||||
curl_setopt($curlHandle, CURLOPT_URL, $fullUrl.'&'.http_build_query($arguments));
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
|
||||
break;
|
||||
|
||||
case 'patch':
|
||||
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'PATCH');
|
||||
$this->attachRequestPayload($curlHandle, $arguments);
|
||||
|
||||
break;
|
||||
|
||||
case 'put':
|
||||
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'PUT');
|
||||
$this->attachRequestPayload($curlHandle, $arguments);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$body = json_decode(curl_exec($curlHandle), true);
|
||||
$headers = curl_getinfo($curlHandle);
|
||||
$error = curl_error($curlHandle);
|
||||
|
||||
return new Response($headers, $body, $error);
|
||||
}
|
||||
|
||||
private function attachRequestPayload(&$curlHandle, array $data)
|
||||
{
|
||||
$encoded = json_encode($data);
|
||||
|
||||
$this->lastRequest['body'] = $encoded;
|
||||
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $encoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fullUrl
|
||||
* @param array $headers
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private function getCurlHandle(string $fullUrl, array $headers = [])
|
||||
{
|
||||
$curlHandle = curl_init();
|
||||
|
||||
curl_setopt($curlHandle, CURLOPT_URL, $fullUrl);
|
||||
|
||||
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array_merge([
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/json',
|
||||
], $headers));
|
||||
|
||||
curl_setopt($curlHandle, CURLOPT_USERAGENT, 'Laravel/Flare API 1.0');
|
||||
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curlHandle, CURLOPT_TIMEOUT, $this->timeout);
|
||||
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, true);
|
||||
curl_setopt($curlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
curl_setopt($curlHandle, CURLOPT_ENCODING, '');
|
||||
curl_setopt($curlHandle, CURLINFO_HEADER_OUT, true);
|
||||
curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($curlHandle, CURLOPT_MAXREDIRS, 1);
|
||||
|
||||
return $curlHandle;
|
||||
}
|
||||
}
|
||||
21
vendor/facade/flare-client-php/src/Http/Exceptions/BadResponse.php
vendored
Normal file
21
vendor/facade/flare-client-php/src/Http/Exceptions/BadResponse.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Facade\FlareClient\Http\Response;
|
||||
|
||||
class BadResponse extends Exception
|
||||
{
|
||||
/** @var \Facade\FlareClient\Http\Response */
|
||||
public $response;
|
||||
|
||||
public static function createForResponse(Response $response)
|
||||
{
|
||||
$exception = new static("Could not perform request because: {$response->getError()}");
|
||||
|
||||
$exception->response = $response;
|
||||
|
||||
return $exception;
|
||||
}
|
||||
}
|
||||
33
vendor/facade/flare-client-php/src/Http/Exceptions/BadResponseCode.php
vendored
Normal file
33
vendor/facade/flare-client-php/src/Http/Exceptions/BadResponseCode.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Facade\FlareClient\Http\Response;
|
||||
|
||||
class BadResponseCode extends Exception
|
||||
{
|
||||
/** @var \Facade\FlareClient\Http\Response */
|
||||
public $response;
|
||||
|
||||
/** @var array */
|
||||
public $errors;
|
||||
|
||||
public static function createForResponse(Response $response)
|
||||
{
|
||||
$exception = new static(static::getMessageForResponse($response));
|
||||
|
||||
$exception->response = $response;
|
||||
|
||||
$bodyErrors = isset($response->getBody()['errors']) ? $response->getBody()['errors'] : [];
|
||||
|
||||
$exception->errors = $bodyErrors;
|
||||
|
||||
return $exception;
|
||||
}
|
||||
|
||||
public static function getMessageForResponse(Response $response)
|
||||
{
|
||||
return "Response code {$response->getHttpResponseCode()} returned";
|
||||
}
|
||||
}
|
||||
13
vendor/facade/flare-client-php/src/Http/Exceptions/InvalidData.php
vendored
Normal file
13
vendor/facade/flare-client-php/src/Http/Exceptions/InvalidData.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http\Exceptions;
|
||||
|
||||
use Facade\FlareClient\Http\Response;
|
||||
|
||||
class InvalidData extends BadResponseCode
|
||||
{
|
||||
public static function getMessageForResponse(Response $response)
|
||||
{
|
||||
return 'Invalid data found';
|
||||
}
|
||||
}
|
||||
13
vendor/facade/flare-client-php/src/Http/Exceptions/MissingParameter.php
vendored
Normal file
13
vendor/facade/flare-client-php/src/Http/Exceptions/MissingParameter.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class MissingParameter extends Exception
|
||||
{
|
||||
public static function create(string $parameterName)
|
||||
{
|
||||
return new static("`$parameterName` is a required parameter");
|
||||
}
|
||||
}
|
||||
13
vendor/facade/flare-client-php/src/Http/Exceptions/NotFound.php
vendored
Normal file
13
vendor/facade/flare-client-php/src/Http/Exceptions/NotFound.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http\Exceptions;
|
||||
|
||||
use Facade\FlareClient\Http\Response;
|
||||
|
||||
class NotFound extends BadResponseCode
|
||||
{
|
||||
public static function getMessageForResponse(Response $response)
|
||||
{
|
||||
return 'Not found';
|
||||
}
|
||||
}
|
||||
65
vendor/facade/flare-client-php/src/Http/Response.php
vendored
Normal file
65
vendor/facade/flare-client-php/src/Http/Response.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Http;
|
||||
|
||||
class Response
|
||||
{
|
||||
private $headers;
|
||||
|
||||
private $body;
|
||||
|
||||
private $error;
|
||||
|
||||
public function __construct($headers, $body, $error)
|
||||
{
|
||||
$this->headers = $headers;
|
||||
|
||||
$this->body = $body;
|
||||
|
||||
$this->error = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBody()
|
||||
{
|
||||
return $this->body != false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int
|
||||
*/
|
||||
public function getHttpResponseCode()
|
||||
{
|
||||
if (! isset($this->headers['http_code'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
return (int) $this->headers['http_code'];
|
||||
}
|
||||
}
|
||||
26
vendor/facade/flare-client-php/src/Middleware/AddGlows.php
vendored
Normal file
26
vendor/facade/flare-client-php/src/Middleware/AddGlows.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Middleware;
|
||||
|
||||
use Facade\FlareClient\Glows\Recorder;
|
||||
use Facade\FlareClient\Report;
|
||||
|
||||
class AddGlows
|
||||
{
|
||||
/** @var Recorder */
|
||||
private $recorder;
|
||||
|
||||
public function __construct(Recorder $recorder)
|
||||
{
|
||||
$this->recorder = $recorder;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
foreach ($this->recorder->glows() as $glow) {
|
||||
$report->addGlow($glow);
|
||||
}
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
19
vendor/facade/flare-client-php/src/Middleware/AnonymizeIp.php
vendored
Normal file
19
vendor/facade/flare-client-php/src/Middleware/AnonymizeIp.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
|
||||
class AnonymizeIp
|
||||
{
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$context = $report->allContext();
|
||||
|
||||
$context['request']['ip'] = null;
|
||||
|
||||
$report->userProvidedContext($context);
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
30
vendor/facade/flare-client-php/src/Middleware/CensorRequestBodyFields.php
vendored
Normal file
30
vendor/facade/flare-client-php/src/Middleware/CensorRequestBodyFields.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
|
||||
class CensorRequestBodyFields
|
||||
{
|
||||
protected $fieldNames = [];
|
||||
|
||||
public function __construct(array $fieldNames)
|
||||
{
|
||||
$this->fieldNames = $fieldNames;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$context = $report->allContext();
|
||||
|
||||
foreach ($this->fieldNames as $fieldName) {
|
||||
if (isset($context['request_data']['body'][$fieldName])) {
|
||||
$context['request_data']['body'][$fieldName] = '<CENSORED>';
|
||||
}
|
||||
}
|
||||
|
||||
$report->userProvidedContext($context);
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
334
vendor/facade/flare-client-php/src/Report.php
vendored
Normal file
334
vendor/facade/flare-client-php/src/Report.php
vendored
Normal file
@@ -0,0 +1,334 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient;
|
||||
|
||||
use Facade\FlareClient\Concerns\HasContext;
|
||||
use Facade\FlareClient\Concerns\UsesTime;
|
||||
use Facade\FlareClient\Context\ContextInterface;
|
||||
use Facade\FlareClient\Contracts\ProvidesFlareContext;
|
||||
use Facade\FlareClient\Enums\GroupingTypes;
|
||||
use Facade\FlareClient\Glows\Glow;
|
||||
use Facade\FlareClient\Solutions\ReportSolution;
|
||||
use Facade\FlareClient\Stacktrace\Stacktrace;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
use Throwable;
|
||||
|
||||
class Report
|
||||
{
|
||||
use UsesTime;
|
||||
use HasContext;
|
||||
|
||||
/** @var \Facade\FlareClient\Stacktrace\Stacktrace */
|
||||
private $stacktrace;
|
||||
|
||||
/** @var string */
|
||||
private $exceptionClass;
|
||||
|
||||
/** @var string */
|
||||
private $message;
|
||||
|
||||
/** @var array */
|
||||
private $glows = [];
|
||||
|
||||
/** @var array */
|
||||
private $solutions = [];
|
||||
|
||||
/** @var ContextInterface */
|
||||
private $context;
|
||||
|
||||
/** @var string */
|
||||
private $applicationPath;
|
||||
|
||||
/** @var ?string */
|
||||
private $applicationVersion;
|
||||
|
||||
/** @var array */
|
||||
private $userProvidedContext = [];
|
||||
|
||||
/** @var array */
|
||||
private $exceptionContext = [];
|
||||
|
||||
/** @var Throwable */
|
||||
private $throwable;
|
||||
|
||||
/** @var string */
|
||||
private $notifierName;
|
||||
|
||||
/** @var string */
|
||||
private $languageVersion;
|
||||
|
||||
/** @var string */
|
||||
private $frameworkVersion;
|
||||
|
||||
/** @var int */
|
||||
private $openFrameIndex;
|
||||
|
||||
/** @var string */
|
||||
private $groupBy ;
|
||||
|
||||
/** @var string */
|
||||
private $trackingUuid;
|
||||
|
||||
/** @var null string|null */
|
||||
public static $fakeTrackingUuid = null;
|
||||
|
||||
public static function createForThrowable(
|
||||
Throwable $throwable,
|
||||
ContextInterface $context,
|
||||
?string $applicationPath = null,
|
||||
?string $version = null
|
||||
): self {
|
||||
return (new static())
|
||||
->setApplicationPath($applicationPath)
|
||||
->throwable($throwable)
|
||||
->useContext($context)
|
||||
->exceptionClass(self::getClassForThrowable($throwable))
|
||||
->message($throwable->getMessage())
|
||||
->stackTrace(Stacktrace::createForThrowable($throwable, $applicationPath))
|
||||
->exceptionContext($throwable)
|
||||
->setApplicationVersion($version);
|
||||
}
|
||||
|
||||
protected static function getClassForThrowable(Throwable $throwable): string
|
||||
{
|
||||
if ($throwable instanceof \Facade\Ignition\Exceptions\ViewException) {
|
||||
if ($previous = $throwable->getPrevious()) {
|
||||
return get_class($previous);
|
||||
}
|
||||
}
|
||||
|
||||
return get_class($throwable);
|
||||
}
|
||||
|
||||
public static function createForMessage(string $message, string $logLevel, ContextInterface $context, ?string $applicationPath = null): self
|
||||
{
|
||||
$stacktrace = Stacktrace::create($applicationPath);
|
||||
|
||||
return (new static())
|
||||
->setApplicationPath($applicationPath)
|
||||
->message($message)
|
||||
->useContext($context)
|
||||
->exceptionClass($logLevel)
|
||||
->stacktrace($stacktrace)
|
||||
->openFrameIndex($stacktrace->firstApplicationFrameIndex());
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->trackingUuid = self::$fakeTrackingUuid ?? $this->generateUuid();
|
||||
}
|
||||
|
||||
public function trackingUuid(): string
|
||||
{
|
||||
return $this->trackingUuid;
|
||||
}
|
||||
|
||||
public function exceptionClass(string $exceptionClass)
|
||||
{
|
||||
$this->exceptionClass = $exceptionClass;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getExceptionClass(): string
|
||||
{
|
||||
return $this->exceptionClass;
|
||||
}
|
||||
|
||||
public function throwable(Throwable $throwable)
|
||||
{
|
||||
$this->throwable = $throwable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getThrowable(): ?Throwable
|
||||
{
|
||||
return $this->throwable;
|
||||
}
|
||||
|
||||
public function message(string $message)
|
||||
{
|
||||
$this->message = $message;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
public function stacktrace(Stacktrace $stacktrace)
|
||||
{
|
||||
$this->stacktrace = $stacktrace;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStacktrace(): Stacktrace
|
||||
{
|
||||
return $this->stacktrace;
|
||||
}
|
||||
|
||||
public function notifierName(string $notifierName)
|
||||
{
|
||||
$this->notifierName = $notifierName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function languageVersion(string $languageVersion)
|
||||
{
|
||||
$this->languageVersion = $languageVersion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function frameworkVersion(string $frameworkVersion)
|
||||
{
|
||||
$this->frameworkVersion = $frameworkVersion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function useContext(ContextInterface $request)
|
||||
{
|
||||
$this->context = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function openFrameIndex(?int $index)
|
||||
{
|
||||
$this->openFrameIndex = $index;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setApplicationPath(?string $applicationPath)
|
||||
{
|
||||
$this->applicationPath = $applicationPath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApplicationPath(): ?string
|
||||
{
|
||||
return $this->applicationPath;
|
||||
}
|
||||
|
||||
public function setApplicationVersion(?string $applicationVersion)
|
||||
{
|
||||
$this->applicationVersion = $applicationVersion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApplicationVersion(): ?string
|
||||
{
|
||||
return $this->applicationVersion;
|
||||
}
|
||||
|
||||
public function view(?View $view)
|
||||
{
|
||||
$this->view = $view;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addGlow(Glow $glow)
|
||||
{
|
||||
$this->glows[] = $glow->toArray();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSolution(Solution $solution)
|
||||
{
|
||||
$this->solutions[] = ReportSolution::fromSolution($solution)->toArray();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function userProvidedContext(array $userProvidedContext)
|
||||
{
|
||||
$this->userProvidedContext = $userProvidedContext;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
public function groupByTopFrame()
|
||||
{
|
||||
$this->groupBy = GroupingTypes::TOP_FRAME;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
public function groupByException()
|
||||
{
|
||||
$this->groupBy = GroupingTypes::EXCEPTION;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function allContext(): array
|
||||
{
|
||||
$context = $this->context->toArray();
|
||||
|
||||
$context = array_merge_recursive_distinct($context, $this->exceptionContext);
|
||||
|
||||
return array_merge_recursive_distinct($context, $this->userProvidedContext);
|
||||
}
|
||||
|
||||
private function exceptionContext(Throwable $throwable)
|
||||
{
|
||||
if ($throwable instanceof ProvidesFlareContext) {
|
||||
$this->exceptionContext = $throwable->context();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'notifier' => $this->notifierName ?? 'Flare Client',
|
||||
'language' => 'PHP',
|
||||
'framework_version' => $this->frameworkVersion,
|
||||
'language_version' => $this->languageVersion ?? phpversion(),
|
||||
'exception_class' => $this->exceptionClass,
|
||||
'seen_at' => $this->getCurrentTime(),
|
||||
'message' => $this->message,
|
||||
'glows' => $this->glows,
|
||||
'solutions' => $this->solutions,
|
||||
'stacktrace' => $this->stacktrace->toArray(),
|
||||
'context' => $this->allContext(),
|
||||
'stage' => $this->stage,
|
||||
'message_level' => $this->messageLevel,
|
||||
'open_frame_index' => $this->openFrameIndex,
|
||||
'application_path' => $this->applicationPath,
|
||||
'application_version' => $this->applicationVersion,
|
||||
'tracking_uuid' => $this->trackingUuid,
|
||||
];
|
||||
}
|
||||
|
||||
/*
|
||||
* Found on https://stackoverflow.com/questions/2040240/php-function-to-generate-v4-uuid/15875555#15875555
|
||||
*/
|
||||
private function generateUuid(): string
|
||||
{
|
||||
// Generate 16 bytes (128 bits) of random data or use the data passed into the function.
|
||||
$data = $data ?? random_bytes(16);
|
||||
|
||||
// Set version to 0100
|
||||
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
|
||||
// Set bits 6-7 to 10
|
||||
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
|
||||
|
||||
// Output the 36 character UUID.
|
||||
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
||||
}
|
||||
}
|
||||
36
vendor/facade/flare-client-php/src/Solutions/ReportSolution.php
vendored
Normal file
36
vendor/facade/flare-client-php/src/Solutions/ReportSolution.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Facade\IgnitionContracts\Solution as SolutionContract;
|
||||
|
||||
class ReportSolution
|
||||
{
|
||||
/** @var SolutionContract */
|
||||
protected $solution;
|
||||
|
||||
public function __construct(SolutionContract $solution)
|
||||
{
|
||||
$this->solution = $solution;
|
||||
}
|
||||
|
||||
public static function fromSolution(SolutionContract $solution)
|
||||
{
|
||||
return new static($solution);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$isRunnable = ($this->solution instanceof RunnableSolution);
|
||||
|
||||
return [
|
||||
'class' => get_class($this->solution),
|
||||
'title' => $this->solution->getSolutionTitle(),
|
||||
'description' => $this->solution->getSolutionDescription(),
|
||||
'links' => $this->solution->getDocumentationLinks(),
|
||||
'action_description' => $isRunnable ? $this->solution->getSolutionActionDescription() : null,
|
||||
'is_runnable' => $isRunnable,
|
||||
];
|
||||
}
|
||||
}
|
||||
72
vendor/facade/flare-client-php/src/Stacktrace/Codesnippet.php
vendored
Normal file
72
vendor/facade/flare-client-php/src/Stacktrace/Codesnippet.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Stacktrace;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class Codesnippet
|
||||
{
|
||||
/** @var int */
|
||||
private $surroundingLine = 1;
|
||||
|
||||
/** @var int */
|
||||
private $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 [];
|
||||
}
|
||||
}
|
||||
|
||||
private function getBounds($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/facade/flare-client-php/src/Stacktrace/File.php
vendored
Normal file
41
vendor/facade/flare-client-php/src/Stacktrace/File.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Stacktrace;
|
||||
|
||||
use SplFileObject;
|
||||
|
||||
class File
|
||||
{
|
||||
/** @var \SplFileObject */
|
||||
private $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();
|
||||
}
|
||||
}
|
||||
71
vendor/facade/flare-client-php/src/Stacktrace/Frame.php
vendored
Normal file
71
vendor/facade/flare-client-php/src/Stacktrace/Frame.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Stacktrace;
|
||||
|
||||
class Frame
|
||||
{
|
||||
/** @var string */
|
||||
private $file;
|
||||
|
||||
/** @var int */
|
||||
private $lineNumber;
|
||||
|
||||
/** @var string */
|
||||
private $method;
|
||||
|
||||
/** @var string */
|
||||
private $class;
|
||||
|
||||
/** @var bool */
|
||||
private $isApplicationFrame;
|
||||
|
||||
public function __construct(
|
||||
string $file,
|
||||
int $lineNumber,
|
||||
string $method = null,
|
||||
string $class = null,
|
||||
bool $isApplicationFrame = false
|
||||
) {
|
||||
$this->file = $file;
|
||||
|
||||
$this->lineNumber = $lineNumber;
|
||||
|
||||
$this->method = $method;
|
||||
|
||||
$this->class = $class;
|
||||
|
||||
$this->isApplicationFrame = $isApplicationFrame;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$codeSnippet = (new Codesnippet())
|
||||
->snippetLineCount(31)
|
||||
->surroundingLine($this->lineNumber)
|
||||
->get($this->file);
|
||||
|
||||
return [
|
||||
'line_number' => $this->lineNumber,
|
||||
'method' => $this->method,
|
||||
'class' => $this->class,
|
||||
'code_snippet' => $codeSnippet,
|
||||
'file' => $this->file,
|
||||
'is_application_frame' => $this->isApplicationFrame,
|
||||
];
|
||||
}
|
||||
|
||||
public function getFile(): string
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
public function getLinenumber(): int
|
||||
{
|
||||
return $this->lineNumber;
|
||||
}
|
||||
|
||||
public function isApplicationFrame()
|
||||
{
|
||||
return $this->isApplicationFrame;
|
||||
}
|
||||
}
|
||||
126
vendor/facade/flare-client-php/src/Stacktrace/Stacktrace.php
vendored
Normal file
126
vendor/facade/flare-client-php/src/Stacktrace/Stacktrace.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Stacktrace;
|
||||
|
||||
use Throwable;
|
||||
|
||||
class Stacktrace
|
||||
{
|
||||
/** @var \Facade\FlareClient\Stacktrace\Frame[] */
|
||||
private $frames;
|
||||
|
||||
/** @var string */
|
||||
private $applicationPath;
|
||||
|
||||
public static function createForThrowable(Throwable $throwable, ?string $applicationPath = null): self
|
||||
{
|
||||
return new static($throwable->getTrace(), $applicationPath, $throwable->getFile(), $throwable->getLine());
|
||||
}
|
||||
|
||||
public static function create(?string $applicationPath = null): self
|
||||
{
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS & ~DEBUG_BACKTRACE_PROVIDE_OBJECT);
|
||||
|
||||
return new static($backtrace, $applicationPath);
|
||||
}
|
||||
|
||||
public function __construct(array $backtrace, ?string $applicationPath = null, string $topmostFile = null, string $topmostLine = null)
|
||||
{
|
||||
$this->applicationPath = $applicationPath;
|
||||
|
||||
$currentFile = $topmostFile;
|
||||
$currentLine = $topmostLine;
|
||||
|
||||
foreach ($backtrace as $rawFrame) {
|
||||
if (! $this->frameFromFlare($rawFrame) && ! $this->fileIgnored($currentFile)) {
|
||||
$this->frames[] = new Frame(
|
||||
$currentFile,
|
||||
$currentLine,
|
||||
$rawFrame['function'] ?? null,
|
||||
$rawFrame['class'] ?? null,
|
||||
$this->frameFileFromApplication($currentFile)
|
||||
);
|
||||
}
|
||||
|
||||
$currentFile = $rawFrame['file'] ?? 'unknown';
|
||||
$currentLine = $rawFrame['line'] ?? 0;
|
||||
}
|
||||
|
||||
$this->frames[] = new Frame(
|
||||
$currentFile,
|
||||
$currentLine,
|
||||
'[top]'
|
||||
);
|
||||
}
|
||||
|
||||
protected function frameFromFlare(array $rawFrame): bool
|
||||
{
|
||||
return isset($rawFrame['class']) && strpos($rawFrame['class'], 'Facade\\FlareClient\\') === 0;
|
||||
}
|
||||
|
||||
protected function frameFileFromApplication(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 fileIgnored(string $currentFile): bool
|
||||
{
|
||||
$currentFile = str_replace('\\', DIRECTORY_SEPARATOR, $currentFile);
|
||||
|
||||
$ignoredFiles = [
|
||||
'/ignition/src/helpers.php',
|
||||
];
|
||||
|
||||
foreach ($ignoredFiles as $ignoredFile) {
|
||||
if (strstr($currentFile, $ignoredFile) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function firstFrame(): Frame
|
||||
{
|
||||
return $this->frames[0];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return array_map(function (Frame $frame) {
|
||||
return $frame->toArray();
|
||||
}, $this->frames);
|
||||
}
|
||||
|
||||
public function firstApplicationFrame(): ?Frame
|
||||
{
|
||||
foreach ($this->frames as $index => $frame) {
|
||||
if ($frame->isApplicationFrame()) {
|
||||
return $frame;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function firstApplicationFrameIndex(): ?int
|
||||
{
|
||||
foreach ($this->frames as $index => $frame) {
|
||||
if ($frame->isApplicationFrame()) {
|
||||
return $index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
13
vendor/facade/flare-client-php/src/Time/SystemTime.php
vendored
Normal file
13
vendor/facade/flare-client-php/src/Time/SystemTime.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Time;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
class SystemTime implements Time
|
||||
{
|
||||
public function getCurrentTime(): int
|
||||
{
|
||||
return (new DateTimeImmutable())->getTimestamp();
|
||||
}
|
||||
}
|
||||
8
vendor/facade/flare-client-php/src/Time/Time.php
vendored
Normal file
8
vendor/facade/flare-client-php/src/Time/Time.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Time;
|
||||
|
||||
interface Time
|
||||
{
|
||||
public function getCurrentTime(): int;
|
||||
}
|
||||
14
vendor/facade/flare-client-php/src/Truncation/AbstractTruncationStrategy.php
vendored
Normal file
14
vendor/facade/flare-client-php/src/Truncation/AbstractTruncationStrategy.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Truncation;
|
||||
|
||||
abstract class AbstractTruncationStrategy implements TruncationStrategy
|
||||
{
|
||||
/** @var ReportTrimmer */
|
||||
protected $reportTrimmer;
|
||||
|
||||
public function __construct(ReportTrimmer $reportTrimmer)
|
||||
{
|
||||
$this->reportTrimmer = $reportTrimmer;
|
||||
}
|
||||
}
|
||||
41
vendor/facade/flare-client-php/src/Truncation/ReportTrimmer.php
vendored
Normal file
41
vendor/facade/flare-client-php/src/Truncation/ReportTrimmer.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Truncation;
|
||||
|
||||
class ReportTrimmer
|
||||
{
|
||||
protected static $maxPayloadSize = 524288;
|
||||
|
||||
protected $strategies = [
|
||||
TrimStringsStrategy::class,
|
||||
TrimContextItemsStrategy::class,
|
||||
];
|
||||
|
||||
public function trim(array $payload): array
|
||||
{
|
||||
foreach ($this->strategies as $strategy) {
|
||||
if (! $this->needsToBeTrimmed($payload)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$payload = (new $strategy($this))->execute($payload);
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
public function needsToBeTrimmed(array $payload): bool
|
||||
{
|
||||
return strlen(json_encode($payload)) > self::getMaxPayloadSize();
|
||||
}
|
||||
|
||||
public static function getMaxPayloadSize(): int
|
||||
{
|
||||
return self::$maxPayloadSize;
|
||||
}
|
||||
|
||||
public static function setMaxPayloadSize(int $maxPayloadSize): void
|
||||
{
|
||||
self::$maxPayloadSize = $maxPayloadSize;
|
||||
}
|
||||
}
|
||||
44
vendor/facade/flare-client-php/src/Truncation/TrimContextItemsStrategy.php
vendored
Normal file
44
vendor/facade/flare-client-php/src/Truncation/TrimContextItemsStrategy.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Truncation;
|
||||
|
||||
class TrimContextItemsStrategy extends AbstractTruncationStrategy
|
||||
{
|
||||
public static function thresholds()
|
||||
{
|
||||
return [100, 50, 25, 10];
|
||||
}
|
||||
|
||||
public function execute(array $payload): array
|
||||
{
|
||||
foreach (static::thresholds() as $threshold) {
|
||||
if (! $this->reportTrimmer->needsToBeTrimmed($payload)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$payload['context'] = $this->iterateContextItems($payload['context'], $threshold);
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
protected function iterateContextItems(array $contextItems, int $threshold): array
|
||||
{
|
||||
array_walk($contextItems, [$this, 'trimContextItems'], $threshold);
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function trimContextItems(&$value, $key, int $threshold)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
if (count($value) > $threshold) {
|
||||
$value = array_slice($value, $threshold * -1, $threshold);
|
||||
}
|
||||
|
||||
array_walk($value, [$this, 'trimContextItems'], $threshold);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
35
vendor/facade/flare-client-php/src/Truncation/TrimStringsStrategy.php
vendored
Normal file
35
vendor/facade/flare-client-php/src/Truncation/TrimStringsStrategy.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Truncation;
|
||||
|
||||
class TrimStringsStrategy extends AbstractTruncationStrategy
|
||||
{
|
||||
public static function thresholds()
|
||||
{
|
||||
return [1024, 512, 256];
|
||||
}
|
||||
|
||||
public function execute(array $payload): array
|
||||
{
|
||||
foreach (static::thresholds() as $threshold) {
|
||||
if (! $this->reportTrimmer->needsToBeTrimmed($payload)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$payload = $this->trimPayloadString($payload, $threshold);
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
protected function trimPayloadString(array $payload, int $threshold): array
|
||||
{
|
||||
array_walk_recursive($payload, function (&$value) use ($threshold) {
|
||||
if (is_string($value) && strlen($value) > $threshold) {
|
||||
$value = substr($value, 0, $threshold);
|
||||
}
|
||||
});
|
||||
|
||||
return $payload;
|
||||
}
|
||||
}
|
||||
8
vendor/facade/flare-client-php/src/Truncation/TruncationStrategy.php
vendored
Normal file
8
vendor/facade/flare-client-php/src/Truncation/TruncationStrategy.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient\Truncation;
|
||||
|
||||
interface TruncationStrategy
|
||||
{
|
||||
public function execute(array $payload): array;
|
||||
}
|
||||
51
vendor/facade/flare-client-php/src/View.php
vendored
Normal file
51
vendor/facade/flare-client-php/src/View.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\FlareClient;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
|
||||
|
||||
class View
|
||||
{
|
||||
/** @var string */
|
||||
private $file;
|
||||
|
||||
/** @var array */
|
||||
private $data = [];
|
||||
|
||||
public function __construct(string $file, array $data = [])
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public static function create(string $file, array $data = []): self
|
||||
{
|
||||
return new static($file, $data);
|
||||
}
|
||||
|
||||
private function dumpViewData($variable): string
|
||||
{
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$dumper = new HtmlDumper();
|
||||
$dumper->setDumpHeader('');
|
||||
|
||||
$output = fopen('php://memory', 'r+b');
|
||||
|
||||
$dumper->dump($cloner->cloneVar($variable)->withMaxDepth(1), $output, [
|
||||
'maxDepth' => 1,
|
||||
'maxStringLength' => 160,
|
||||
]);
|
||||
|
||||
return stream_get_contents($output, -1, 0);
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'file' => $this->file,
|
||||
'data' => array_map([$this, 'dumpViewData'], $this->data),
|
||||
];
|
||||
}
|
||||
}
|
||||
17
vendor/facade/flare-client-php/src/helpers.php
vendored
Normal file
17
vendor/facade/flare-client-php/src/helpers.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('array_merge_recursive_distinct')) {
|
||||
function array_merge_recursive_distinct(array &$array1, array &$array2)
|
||||
{
|
||||
$merged = $array1;
|
||||
foreach ($array2 as $key => &$value) {
|
||||
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
|
||||
$merged[$key] = array_merge_recursive_distinct($merged[$key], $value);
|
||||
} else {
|
||||
$merged[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $merged;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user