Subiendo proyecto completo sin restricciones de git ignore
This commit is contained in:
40
vendor/facade/ignition/.php_cs.php
vendored
Normal file
40
vendor/facade/ignition/.php_cs.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
$finder = Symfony\Component\Finder\Finder::create()
|
||||
->in([
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
])
|
||||
->name('*.php')
|
||||
->notName('*.blade.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);
|
||||
586
vendor/facade/ignition/CHANGELOG.md
vendored
Normal file
586
vendor/facade/ignition/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,586 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to `ignition` will be documented in this file
|
||||
|
||||
## 2.17.6 - 2022-06-30
|
||||
|
||||
### What's Changed
|
||||
|
||||
- notice if dots have been used in the view name by @WebPajooh in https://github.com/facade/ignition/pull/457
|
||||
|
||||
### New Contributors
|
||||
|
||||
- @WebPajooh made their first contribution in https://github.com/facade/ignition/pull/457
|
||||
|
||||
**Full Changelog**: https://github.com/facade/ignition/compare/2.17.5...2.17.6
|
||||
|
||||
## 2.17.5 - 2022-02-23
|
||||
|
||||
## What's Changed
|
||||
|
||||
- fix solutions section padding by @faissaloux in https://github.com/facade/ignition/pull/433
|
||||
- Bump markdown-it from 9.1.0 to 12.3.2 by @dependabot in https://github.com/facade/ignition/pull/446
|
||||
- Bump ajv from 6.10.2 to 6.12.6 by @dependabot in https://github.com/facade/ignition/pull/448
|
||||
- Fix E_NOTICE when requesting invalid script by @cweiske in https://github.com/facade/ignition/pull/449
|
||||
|
||||
## New Contributors
|
||||
|
||||
- @faissaloux made their first contribution in https://github.com/facade/ignition/pull/433
|
||||
- @cweiske made their first contribution in https://github.com/facade/ignition/pull/449
|
||||
|
||||
**Full Changelog**: https://github.com/facade/ignition/compare/2.17.4...2.17.5
|
||||
|
||||
## 2.17.4 - 2021-12-27
|
||||
|
||||
- fix bug where uninitialized property within a job could break Ignition
|
||||
|
||||
## 2.17.3 - 2021-12-23
|
||||
|
||||
- allow filtering route parameters using a `toFlare` method
|
||||
|
||||
## 2.17.2 - 2021-11-29
|
||||
|
||||
## What's Changed
|
||||
|
||||
- Allow overflow-x on solutions with unbreakable words by @willemvb in https://github.com/facade/ignition/pull/431
|
||||
|
||||
**Full Changelog**: https://github.com/facade/ignition/compare/2.17.1...2.17.2
|
||||
|
||||
## 2.17.2 - 2021-11-29
|
||||
|
||||
- scroll overflow on solutions
|
||||
|
||||
## 2.17.1 - 2021-11-25
|
||||
|
||||
- streamline Livewire solutions
|
||||
|
||||
## 2.17.0 - 2021-11-24
|
||||
|
||||
- improve recording of Livewire data
|
||||
|
||||
## 2.16.1 - 2021-11-16
|
||||
|
||||
- allow sending of unbinded sql queries to Flare
|
||||
|
||||
## 2.16.0 - 2021-10-28
|
||||
|
||||
- improve recording data from jobs (#416)
|
||||
|
||||
## 2.15.0 - 2021-10-11
|
||||
|
||||
- improve output of flare:test
|
||||
|
||||
## 2.14.1 - 2021-10-08
|
||||
|
||||
- update base URL for Flare
|
||||
|
||||
## 2.14.0 - 2021-10-01
|
||||
|
||||
- add support for VScode WSL + SSH remote (#420)
|
||||
|
||||
## 2.13.1 - 2021-09-13
|
||||
|
||||
- fix namespace of `SentReports` in facade
|
||||
|
||||
## 2.13.0 - 2021-09-13
|
||||
|
||||
- add tracking uuid (#418)
|
||||
|
||||
## 2.12.1 - 2021-09-08
|
||||
|
||||
- add support for VS Codium editor (#417)
|
||||
|
||||
## 2.12.0 - 2021-08-24
|
||||
|
||||
- add support for collecting information about jobs (#412)
|
||||
|
||||
## 2.11.4 - 2021-08-16
|
||||
|
||||
- use npm ci instead of install (#411)
|
||||
|
||||
## 2.11.3 - 2021-08-16
|
||||
|
||||
- fix issues with circular dependencies in model route parameters (#408)
|
||||
- remove notice about dirty git state in context
|
||||
- wrap `AddGitInformation` middleware in try-catch
|
||||
|
||||
## 2.11.2 - 2021-07-20
|
||||
|
||||
- fix issues introduced in 2.11.1 (#403)
|
||||
|
||||
## 2.11.1 - 2021-07-20
|
||||
|
||||
- fix sending queued reports on Laravel Vapor queues (#398)
|
||||
|
||||
## 2.11.0 - 2021-07-12
|
||||
|
||||
- prepare Laravel 9 support
|
||||
- remove filp/whoops dependency
|
||||
- update front-end dependencies
|
||||
|
||||
## 2.10.2 - 2021-06-11
|
||||
|
||||
- fix typo in config/flare.php (#395)
|
||||
|
||||
## 2.10.1 - 2021-06-03
|
||||
|
||||
- fix memory leaks in Octane (#393)
|
||||
|
||||
## 2.10.0 - 2021-06-03
|
||||
|
||||
- add a solution for lazy loading violations (#392)
|
||||
|
||||
## 2.9.0 - 2021-05-05
|
||||
|
||||
- add Xdebug format links for editor (#383)
|
||||
|
||||
## 2.8.4 - 2021-04-29
|
||||
|
||||
- avoid making call to Flare when no API key is specified
|
||||
|
||||
## 2.8.3 - 2021-04-09
|
||||
|
||||
- support Octane (#379)
|
||||
|
||||
## 2.8.2 - 2021-04-08
|
||||
|
||||
- censor passwords by default (#377)
|
||||
|
||||
## 2.8.1 - 2021-04-08
|
||||
|
||||
- add `censor_request_body_fields` default config option
|
||||
|
||||
## 2.8.0 - 2021-04-08
|
||||
|
||||
- add `censor_request_body_fields` config option
|
||||
|
||||
## 2.7.0 - 2021-03-30
|
||||
|
||||
- adds a debug warning when having debug enabled on a non-local environment (#366)
|
||||
|
||||
## 2.6.1 - 2021-03-30
|
||||
|
||||
- Disable executing solutions on non-local environments or from non-local IP addresses (#364)
|
||||
|
||||
## 2.6.0 - 2021-03-24
|
||||
|
||||
- add extra output to test command when executing verbosely
|
||||
|
||||
## 2.5.14 - 2021-03-03
|
||||
|
||||
- fix ignition not working when there is no argv
|
||||
|
||||
## 2.5.13 - 2021-02-16
|
||||
|
||||
- remove custom grouping
|
||||
|
||||
## 2.5.12 - 2021-02-15
|
||||
|
||||
- fix wrong config usage (#354)
|
||||
|
||||
## 2.5.11 - 2021-02-05
|
||||
|
||||
- fix memory leaks caused by log and query recorder (#344)
|
||||
|
||||
## 2.5.10 - 2021-02-02
|
||||
|
||||
- fix tinker logs not being sent to Flare
|
||||
|
||||
## 2.5.9 - 2021-01-26
|
||||
|
||||
- fix logged context not being sent to Flare
|
||||
|
||||
## 2.5.8 - 2020-12-29
|
||||
|
||||
- fix double `$` on PHP 8 (#338)
|
||||
|
||||
## 2.5.7 - 2020-12-29
|
||||
|
||||
- fix for breaking change in highlight.js (fixes 2.5.5)
|
||||
|
||||
## 2.5.6 - 2020-12-29
|
||||
|
||||
- revert to compiled js of 2.5.3
|
||||
|
||||
## 2.5.5 - 2020-12-29
|
||||
|
||||
- added compiled js of previous release
|
||||
|
||||
## 2.5.4 - 2020-12-29
|
||||
|
||||
- added support for Nova text editor (#343)
|
||||
|
||||
## 2.5.3 - 2020-12-08
|
||||
|
||||
- Use Livewire compatible compiler engine when using Livewire (#340)
|
||||
|
||||
## 2.5.2 - 2020-11-14
|
||||
|
||||
- fix `MakeViewVariableOptionalSolution` to disallow stream wrappers and files that do not end in ".blade.php" (#334)
|
||||
|
||||
## 2.5.1 - 2020-11-13
|
||||
|
||||
- add support for LiveWire component urls
|
||||
|
||||
## 2.5.0 - 2020-10-27
|
||||
|
||||
- add PHP 8.0-dev support
|
||||
- remove unnecessary `scrivo/highlight.php` dependency
|
||||
|
||||
## 2.4.2 - 2021-03-08
|
||||
|
||||
- fix `MakeViewVariableOptionalSolution` to disallow stream wrappers and files that do not end in .blade.php (#356)
|
||||
|
||||
## 2.4.1 - 2020-10-14
|
||||
|
||||
- fix copy casing
|
||||
|
||||
## 2.4.0 - 2020-10-14
|
||||
|
||||
- add livewire component discovery solution
|
||||
|
||||
## 2.3.8 - 2020-10-02
|
||||
|
||||
- Address Missing Mix Manifest Error (#317)
|
||||
|
||||
## 2.3.7 - 2020-09-06
|
||||
|
||||
- add loading state on share button (#309)
|
||||
- compatibility fix for L8
|
||||
|
||||
## 2.3.6 - 2020-08-10
|
||||
|
||||
- possible security vulnerability: bump elliptic version (#300)
|
||||
- possible XSS vulnerability: escape characters in stacktrace and exception title
|
||||
|
||||
## 2.3.5 - 2020-08-01
|
||||
|
||||
- catch exception in detectLineNumber for not existing blade files (#299)
|
||||
|
||||
## 2.3.4 - 2020-07-27
|
||||
|
||||
- fix an error that would throw a blank page when using third party extensions
|
||||
|
||||
## 2.3.3 -2020-07-14
|
||||
|
||||
- fix all psalm related issues
|
||||
|
||||
## 2.3.2 - 2020-07-14
|
||||
|
||||
- properly bind singleton (#291)
|
||||
|
||||
## 2.3.1 - 2020-07-13
|
||||
|
||||
- improve db name solution (#289)
|
||||
|
||||
## 2.3.0 - 2020-07-13
|
||||
|
||||
- allow override of Dumper via `$_SERVER variable` (#271)
|
||||
- make DumpHandler instance manually in DumpRecorder (#286)
|
||||
- only setup queues when queue is available (#287)
|
||||
|
||||
## 2.2.0 - 2020-07-13
|
||||
|
||||
- add `ignition:make:solution-provider` command
|
||||
|
||||
## 2.1.0 - 2020-07-13
|
||||
|
||||
- add "Undefined Property" solution (#264)
|
||||
|
||||
## 2.0.10 - 2020-07-13
|
||||
|
||||
- correctly detect dump location from ddd (#216)
|
||||
|
||||
## 2.0.9 - 2020-07-13
|
||||
|
||||
- use application contract instead of concrete class (#243)
|
||||
|
||||
## 2.0.8 - 2020-07-12
|
||||
|
||||
- do not render solution title tag for empty titles
|
||||
|
||||
## 2.0.7 - 2020-06-07
|
||||
|
||||
- Fix `DefaultDbNameSolutionProvider` (#277)
|
||||
|
||||
## 2.0.6 - 2020-06-01
|
||||
|
||||
- remove ability to fix variable names
|
||||
|
||||
## 2.0.5 - 2020-05-29
|
||||
|
||||
- blacklist certain variable names when fixing variable names
|
||||
|
||||
## 2.0.4 - 2020-05-18
|
||||
|
||||
- handle exceptions in case the request doesn't have a user (#274)
|
||||
|
||||
## 2.0.3 - 2020-04-07
|
||||
|
||||
- support Laravel 8
|
||||
|
||||
## 2.0.2 - 2020-03-18
|
||||
|
||||
- fix execute solution route not defined (#265)
|
||||
|
||||
## 2.0.0 - 2020-02-02
|
||||
|
||||
- adds support for Laravel 7
|
||||
- drop support for Laravel 6 and below
|
||||
- git information won't be collected by default anymore (if you need this set `collect_git_information` to `true` in the `flare` config file)
|
||||
- `MissingPackageSolutionProvider` was added to the `ignored_solution_providers` because it potentially could be slow.
|
||||
|
||||
## 1.16.0 - 2020-01-21
|
||||
|
||||
- add named routes (#197)
|
||||
|
||||
## 1.15.0 - 2020-01-21
|
||||
|
||||
- add exception to the bottom of the html (#230)
|
||||
|
||||
## 1.14.0 - 2020-01-06
|
||||
|
||||
- add indicator that solution is running (#212)
|
||||
|
||||
## 1.13.1 - 2020-01-02
|
||||
|
||||
- Remove external reference for icons (#134)
|
||||
|
||||
## 1.13.0 - 2019-11-27
|
||||
|
||||
- Allow custom grouping types
|
||||
|
||||
## 1.12.1 - 2019-11-25
|
||||
|
||||
- Detect multibyte position offsets when adding linenumbers to the blade view - Fixes #193
|
||||
|
||||
## 1.12.0 - 2019-11-14
|
||||
|
||||
- Add exception to html (#206)
|
||||
- Add a clear exception when passing no parameters to ddd (#205)
|
||||
- Ignore JS tests (#215)
|
||||
- Fix share report route bug
|
||||
|
||||
## 1.11.2 - 2019-10-13
|
||||
|
||||
- simplify default Laravel installation (#198)
|
||||
|
||||
## 1.11.1 - 2019-10-08
|
||||
|
||||
- add conditional line number (#182)
|
||||
|
||||
## 1.11.0 - 2019-10-08
|
||||
|
||||
- add better error messages for missing validation rules (#125)
|
||||
|
||||
## 1.10.0 - 2019-10-07
|
||||
|
||||
- Add `ignition:make-solution` command
|
||||
- Add default for query binding option (Fixes #183)
|
||||
|
||||
## 1.9.2 - 2019-10-04
|
||||
|
||||
- Fix service provider registration (Fixes #177)
|
||||
|
||||
## 1.9.1 - 2019-10-01
|
||||
|
||||
- collapse vendor frames on windows fix (#176)
|
||||
|
||||
## 1.9.0 - 2019-09-27
|
||||
|
||||
- add ability to send logs to flare
|
||||
- add `ddd` function
|
||||
|
||||
## 1.8.4 - 2019-09-27
|
||||
|
||||
- Resolve configuration from the injected app instead of the helper ([#168](https://github.com/facade/ignition/pull/168))
|
||||
|
||||
## 1.8.3 - 2019-09-25
|
||||
|
||||
- Remove `select-none` from error message
|
||||
- Change line clamp behaviour for longer error messages
|
||||
|
||||
## 1.8.2 - 2019-09-20
|
||||
|
||||
- fix for `TypeError: Cannot set property 'highlightState' of undefined`
|
||||
|
||||
## 1.8.1 - 2019-09-20
|
||||
|
||||
- Revert javascript assets via URL - Fixes #161
|
||||
|
||||
## 1.8.0 - 2019-09-18
|
||||
|
||||
- added solution for running Laravel Dusk in production ([#121](https://github.com/facade/ignition/pull/121))
|
||||
- Automatically fix blade variable typos and optional variables ([#38](https://github.com/facade/ignition/pull/38))
|
||||
|
||||
## 1.7.1 - 2019-09-18
|
||||
|
||||
- Use url helper to generate housekeeping endpoints
|
||||
|
||||
## 1.7.0 - 2019-09-18
|
||||
|
||||
- Add the ability to define a query collector max value ([#153](https://github.com/facade/ignition/pull/153))
|
||||
|
||||
## 1.6.10 - 2019-09-18
|
||||
|
||||
- fix `__invoke` method name in solution ([#151](https://github.com/facade/ignition/pull/151))
|
||||
|
||||
## 1.6.9 - 2019-09-18
|
||||
|
||||
- Add noscript trace information - fixes [#146](https://github.com/facade/ignition/issues/146)
|
||||
|
||||
## 1.6.8 - 2019-09-18
|
||||
|
||||
- Use javascript content type for asset response - fixes [#149](https://github.com/facade/ignition/issues/149)
|
||||
|
||||
## 1.6.7 - 2019-09-18
|
||||
|
||||
- Load javascript assets via URL. Fixes [#16](https://github.com/facade/ignition/issues/16)
|
||||
|
||||
## 1.6.6 - 2019-09-16
|
||||
|
||||
- Prevent undefined index exception in `TestCommand`
|
||||
|
||||
## 1.6.5 - 2019-09-13
|
||||
|
||||
- Ignore invalid characters in JSON encoding. Fixes [#138](https://github.com/facade/ignition/issues/138)
|
||||
|
||||
## 1.6.4 - 2019-09-13
|
||||
|
||||
- add no-index on error page
|
||||
|
||||
## 1.6.3 - 2019-09-12
|
||||
|
||||
- Fix `RouteNotDefinedSolutionProvider` in Laravel 5
|
||||
|
||||
## 1.6.2 - 2019-09-12
|
||||
|
||||
- updated publishing tag from default config
|
||||
|
||||
## 1.6.1 - 2019-09-12
|
||||
|
||||
- Resolve configuration from the injected application instead of the helper - Fixes [#131](https://github.com/facade/ignition/issues/131)
|
||||
|
||||
## 1.6.0 - 2019-09-09
|
||||
|
||||
- add `RouteNotDefined` solution provider ([#113](https://github.com/facade/ignition/pull/113))
|
||||
|
||||
## 1.5.0 - 2019-09-09
|
||||
|
||||
- suggest running migrations when a column is missing ([#83](https://github.com/facade/ignition/pull/83))
|
||||
|
||||
## 1.4.19 - 2019-09-09
|
||||
|
||||
- Remove quotation from git commit url ([#89](https://github.com/facade/ignition/pull/89))
|
||||
|
||||
## 1.4.18 - 2019-09-09
|
||||
|
||||
- Fix open_basedir restriction when looking up config file. Fixes ([#120](https://github.com/facade/ignition/pull/120))
|
||||
|
||||
## 1.4.17 - 2019-09-06
|
||||
|
||||
- Remove Inter, Operator from font stack. Fixes [#74](https://github.com/facade/ignition/issues/74)
|
||||
|
||||
## 1.4.15 - 2019-09-05
|
||||
|
||||
- Use previous exception trace for view exceptions. Fixes [#107](https://github.com/facade/ignition/issues/107)
|
||||
|
||||
## 1.4.14 - 2019-09-05
|
||||
|
||||
- Use DIRECTORY_SEPARATOR to fix an issue with blade view lookups in Windows
|
||||
|
||||
## 1.4.13 - 2019-09-05
|
||||
|
||||
- Use Laravel style comments
|
||||
|
||||
## 1.4.12 - 2019-09-04
|
||||
|
||||
- Use a middleware to protect ignition routes ([#93](https://github.com/facade/ignition/pull/93))
|
||||
|
||||
## 1.4.11 - 2019-09-04
|
||||
|
||||
- Use exception line number as fallbacks for view errors
|
||||
|
||||
## 1.4.10 - 2019-09-04
|
||||
|
||||
- Wrap solution provider lookup in a try-catch block
|
||||
|
||||
## 1.4.9 - 2019-09-04
|
||||
|
||||
- Lookup the first exception when linking to Telescope
|
||||
|
||||
## 1.4.8 - 2019-09-04
|
||||
|
||||
- pass an empty string to query if no connection name is available - fixes [#86](https://github.com/facade/ignition/issues/86)
|
||||
|
||||
## 1.4.7 - 2019-09-04
|
||||
|
||||
- Match whoops minimum version constraint with Laravel 6
|
||||
|
||||
## 1.4.6 - 2019-09-04
|
||||
|
||||
- Use empty array for default ignored solution providers
|
||||
|
||||
## 1.4.5 - 2019-09-03
|
||||
|
||||
- fix for new Laravel 6 installs
|
||||
|
||||
## 1.4.4 - 2019-09-03
|
||||
|
||||
- Suggest default database name in Laravel 6
|
||||
- Add void return type to FlareHandler::write()
|
||||
|
||||
## 1.4.3 - 2019-09-03
|
||||
|
||||
- allow monolog v2
|
||||
|
||||
## 1.4.2 - 2019-09-03
|
||||
|
||||
- style fixes
|
||||
|
||||
## 1.4.1 - 2019-09-03
|
||||
|
||||
- Change `remote-sites-path` and `local-sites-path` config keys to us snake case
|
||||
|
||||
## 1.4.0 - 2019-09-03
|
||||
|
||||
- add `enable_runnable_solutions` key to config file
|
||||
|
||||
## 1.3.0 - 2019-09-02
|
||||
|
||||
- add `MergeConflictSolutionProvider`
|
||||
|
||||
## 1.2.0 - 2019-09-02
|
||||
|
||||
- add `ignored_solution_providers` key to config file
|
||||
|
||||
## 1.1.1 - 2019-09-02
|
||||
|
||||
- Fixed context tab crash when not using git ([#24](https://github.com/facade/ignition/issues/24))
|
||||
|
||||
## 1.1.0 - 2019-09-02
|
||||
|
||||
- Fixed an error that removed the ability to register custom blade directives.
|
||||
- Fixed an error that prevented solution execution in Laravel 5.5 and 5.6
|
||||
- The "Share" button can now be disabled in the configuration file
|
||||
- Fixes an error when trying to log `null` values
|
||||
|
||||
## 1.0.4 - 2019-09-02
|
||||
|
||||
- Check if the authenticated user has a `toArray` method available, before collecting user data
|
||||
|
||||
## 1.0.3 - 2019-09-02
|
||||
|
||||
- Corrected invalid link in config file
|
||||
|
||||
## 1.0.2 - 2019-09-02
|
||||
|
||||
- Fixed an error in the `DefaultDbNameSolutionProvider` that could cause an infinite loop in Laravel < 5.6.28
|
||||
|
||||
## 1.0.1 - 2019-08-31
|
||||
|
||||
- add support for L5.5 & 5.6 ([#21](https://github.com/facade/ignition/pull/21))
|
||||
|
||||
## 1.0.0 - 2019-08-30
|
||||
|
||||
- initial release
|
||||
21
vendor/facade/ignition/LICENSE.md
vendored
Normal file
21
vendor/facade/ignition/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.
|
||||
30
vendor/facade/ignition/README.md
vendored
Normal file
30
vendor/facade/ignition/README.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Ignition: a beautiful error page for Laravel apps
|
||||
|
||||
[](https://packagist.org/packages/facade/ignition)
|
||||

|
||||
[](https://packagist.org/packages/facade/ignition)
|
||||
|
||||
[Ignition](https://flareapp.io/docs/ignition-for-laravel/introduction) is a beautiful and customizable error page for Laravel applications running on Laravel 5.5 up Laravel 8. It is the default error page for all Laravel 6 applications. It also allows to publicly share your errors on [Flare](https://flareapp.io). If configured with a valid Flare API key, your errors in production applications will be tracked, and you'll get notified when they happen.
|
||||
|
||||
## Using Laravel 8 or above?
|
||||
|
||||
If you're on Laravel 8 or above, you can switch to [spatie/laravel-ignition](https://github.com/spatie/laravel-ignition), which is a drop-in replacement.
|
||||
Replace `facade/ignition` with `"spatie/laravel-ignition": "^1.0"` in your application's `composer.json` file.
|
||||
|
||||
Going forward, we'll only add security fixes to facade/ignition and highly encourage you to switch to spatie/laravel-ignition.
|
||||
|
||||
## Official Documentation
|
||||
|
||||
The official documentation for Ignition can be found on the [Flare website](https://flareapp.io/docs/ignition-for-laravel/installation).
|
||||
|
||||
### Changelog
|
||||
|
||||
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
||||
3
vendor/facade/ignition/SECURITY.md
vendored
Normal file
3
vendor/facade/ignition/SECURITY.md
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Security Policy
|
||||
|
||||
For security related problems, please don't use the public issue tracker, but mail info@spatie.be.
|
||||
77
vendor/facade/ignition/composer.json
vendored
Normal file
77
vendor/facade/ignition/composer.json
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "facade/ignition",
|
||||
"description": "A beautiful error page for Laravel applications.",
|
||||
"keywords": [
|
||||
"error",
|
||||
"page",
|
||||
"laravel",
|
||||
"flare"
|
||||
],
|
||||
"homepage": "https://github.com/facade/ignition",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.2.5|^8.0",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"facade/flare-client-php": "^1.9.1",
|
||||
"facade/ignition-contracts": "^1.0.2",
|
||||
"illuminate/support": "^7.0|^8.0",
|
||||
"monolog/monolog": "^2.0",
|
||||
"symfony/console": "^5.0",
|
||||
"symfony/var-dumper": "^5.0",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"livewire/livewire": "^2.4",
|
||||
"mockery/mockery": "^1.3",
|
||||
"orchestra/testbench": "^5.0|^6.0",
|
||||
"psalm/plugin-laravel": "^1.2"
|
||||
},
|
||||
"suggest": {
|
||||
"laravel/telescope": "^3.1"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Facade\\Ignition\\IgnitionServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Flare": "Facade\\Ignition\\Facades\\Flare"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facade\\Ignition\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Facade\\Ignition\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"scripts": {
|
||||
"psalm": "vendor/bin/psalm",
|
||||
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes",
|
||||
"test": "vendor/bin/phpunit",
|
||||
"test-coverage": "vendor/bin/phpunit --coverage-html coverage"
|
||||
},
|
||||
"support": {
|
||||
"issues": "https://github.com/facade/ignition/issues",
|
||||
"forum": "https://twitter.com/flareappio",
|
||||
"source": "https://github.com/facade/ignition",
|
||||
"docs": "https://flareapp.io/docs/ignition-for-laravel/introduction"
|
||||
}
|
||||
}
|
||||
62
vendor/facade/ignition/config/flare.php
vendored
Normal file
62
vendor/facade/ignition/config/flare.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
|
|
||||
|--------------------------------------------------------------------------
|
||||
| Flare API key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify Flare's API key below to enable error reporting to the service.
|
||||
|
|
||||
| More info: https://flareapp.io/docs/general/projects
|
||||
|
|
||||
*/
|
||||
|
||||
'key' => env('FLARE_KEY'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Reporting Options
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These options determine which information will be transmitted to Flare.
|
||||
|
|
||||
*/
|
||||
|
||||
'reporting' => [
|
||||
'anonymize_ips' => true,
|
||||
'collect_git_information' => false,
|
||||
'report_queries' => true,
|
||||
'maximum_number_of_collected_queries' => 200,
|
||||
'report_query_bindings' => true,
|
||||
'report_view_data' => true,
|
||||
'grouping_type' => null,
|
||||
'report_logs' => true,
|
||||
'maximum_number_of_collected_logs' => 200,
|
||||
'censor_request_body_fields' => ['password'],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Reporting Log statements
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If this setting is `false` log statements won't be sent as events to Flare,
|
||||
| no matter which error level you specified in the Flare log channel.
|
||||
|
|
||||
*/
|
||||
|
||||
'send_logs_as_events' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Censor request body fields
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These fields will be censored from your request when sent to Flare.
|
||||
|
|
||||
*/
|
||||
|
||||
'censor_request_body_fields' => ['password'],
|
||||
];
|
||||
126
vendor/facade/ignition/config/ignition.php
vendored
Normal file
126
vendor/facade/ignition/config/ignition.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Editor
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Choose your preferred editor to use when clicking any edit button.
|
||||
|
|
||||
| Supported: "phpstorm", "vscode", "vscode-insiders", "vscodium", "textmate", "emacs",
|
||||
| "sublime", "atom", "nova", "macvim", "idea", "netbeans",
|
||||
| "xdebug"
|
||||
|
|
||||
*/
|
||||
|
||||
'editor' => env('IGNITION_EDITOR', 'phpstorm'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Theme
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify which theme Ignition should use.
|
||||
|
|
||||
| Supported: "light", "dark", "auto"
|
||||
|
|
||||
*/
|
||||
|
||||
'theme' => env('IGNITION_THEME', 'light'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sharing
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You can share local errors with colleagues or others around the world.
|
||||
| Sharing is completely free and doesn't require an account on Flare.
|
||||
|
|
||||
| If necessary, you can completely disable sharing below.
|
||||
|
|
||||
*/
|
||||
|
||||
'enable_share_button' => env('IGNITION_SHARING_ENABLED', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Ignition commands
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Ignition comes with an additional make command that lets you create
|
||||
| new solution classes more easily. To keep your default Laravel
|
||||
| installation clean, this command is not registered by default.
|
||||
|
|
||||
| You can enable the command registration below.
|
||||
|
|
||||
*/
|
||||
'register_commands' => env('REGISTER_IGNITION_COMMANDS', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Ignored Solution Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You may specify a list of solution providers (as fully qualified class
|
||||
| names) that shouldn't be loaded. Ignition will ignore these classes
|
||||
| and possible solutions provided by them will never be displayed.
|
||||
|
|
||||
*/
|
||||
|
||||
'ignored_solution_providers' => [
|
||||
\Facade\Ignition\SolutionProviders\MissingPackageSolutionProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Runnable Solutions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Some solutions that Ignition displays are runnable and can perform
|
||||
| various tasks. Runnable solutions are enabled when your app has
|
||||
| debug mode enabled. You may also fully disable this feature.
|
||||
|
|
||||
*/
|
||||
|
||||
'enable_runnable_solutions' => env('IGNITION_ENABLE_RUNNABLE_SOLUTIONS', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Remote Path Mapping
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If you are using a remote dev server, like Laravel Homestead, Docker, or
|
||||
| even a remote VPS, it will be necessary to specify your path mapping.
|
||||
|
|
||||
| Leaving one, or both of these, empty or null will not trigger the remote
|
||||
| URL changes and Ignition will treat your editor links as local files.
|
||||
|
|
||||
| "remote_sites_path" is an absolute base path for your sites or projects
|
||||
| in Homestead, Vagrant, Docker, or another remote development server.
|
||||
|
|
||||
| Example value: "/home/vagrant/Code"
|
||||
|
|
||||
| "local_sites_path" is an absolute base path for your sites or projects
|
||||
| on your local computer where your IDE or code editor is running on.
|
||||
|
|
||||
| Example values: "/Users/<name>/Code", "C:\Users\<name>\Documents\Code"
|
||||
|
|
||||
*/
|
||||
|
||||
'remote_sites_path' => env('IGNITION_REMOTE_SITES_PATH', ''),
|
||||
'local_sites_path' => env('IGNITION_LOCAL_SITES_PATH', ''),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Housekeeping Endpoint Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Ignition registers a couple of routes when it is enabled. Below you may
|
||||
| specify a route prefix that will be used to host all internal links.
|
||||
|
|
||||
*/
|
||||
'housekeeping_endpoint_prefix' => '_ignition',
|
||||
|
||||
];
|
||||
65
vendor/facade/ignition/package.json
vendored
Normal file
65
vendor/facade/ignition/package.json
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "webpack --mode development --watch",
|
||||
"build": "NODE_ENV=production webpack --mode production",
|
||||
"format": "prettier --write 'resources/**/*.{css,js,ts,vue}'"
|
||||
},
|
||||
"dependencies": {
|
||||
"git-url-parse": "^11.1.2",
|
||||
"highlight.js": "^10.4.1",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^12.3.2",
|
||||
"md5": "^2.2.1",
|
||||
"sql-formatter": "^2.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.4.5",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/plugin-transform-runtime": "^7.4.4",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/preset-typescript": "^7.3.3",
|
||||
"@fullhuman/postcss-purgecss": "^1.1.0",
|
||||
"@types/jest": "^24.0.15",
|
||||
"@types/lodash": "^4.14.133",
|
||||
"babel-loader": "^8.0.6",
|
||||
"css-loader": "^3.0.0",
|
||||
"husky": "^1.3.1",
|
||||
"jest": "^24.8.0",
|
||||
"lint-staged": "^8.1.5",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.6.0",
|
||||
"prettier": "^1.16.4",
|
||||
"style-loader": "^0.23.1",
|
||||
"tailwindcss": "^1.0.4",
|
||||
"typescript": "^3.5.2",
|
||||
"vue": "^2.6.10",
|
||||
"vue-loader": "^15.7.0",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"webpack": "^4.35.0",
|
||||
"webpack-cli": "^3.3.5"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged && yarn build && git add resources/compiled/ignition.js"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"linters": {
|
||||
"*.{css,js,ts,vue}": [
|
||||
"yarn format",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"ignore": [
|
||||
"resources/compiled/**/*"
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"testPathIgnorePatterns": [
|
||||
"/node_modules/",
|
||||
"/__helpers__/"
|
||||
]
|
||||
}
|
||||
}
|
||||
51
vendor/facade/ignition/psalm-baseline.xml
vendored
Normal file
51
vendor/facade/ignition/psalm-baseline.xml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="3.17.1@8f211792d813e4dc89f04ed372785ce93b902fd1">
|
||||
<file src="src/IgnitionServiceProvider.php">
|
||||
<UndefinedInterfaceMethod occurrences="7">
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="src/LogRecorder/LogRecorder.php">
|
||||
<UndefinedInterfaceMethod occurrences="1">
|
||||
<code>$this->app</code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="src/QueryRecorder/QueryRecorder.php">
|
||||
<UndefinedInterfaceMethod occurrences="3">
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
<code>$this->app</code>
|
||||
</UndefinedInterfaceMethod>
|
||||
</file>
|
||||
<file src="src/SolutionProviders/MissingLivewireComponentSolutionProvider.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>ComponentNotFoundException</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="src/SolutionProviders/UnknownValidationSolutionProvider.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>app('validator')</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="src/Solutions/LivewireDiscoverSolution.php">
|
||||
<UndefinedClass occurrences="1">
|
||||
<code>LivewireComponentsFinder</code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="src/Views/Engines/CompilerEngine.php">
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$baseException</code>
|
||||
</ParamNameMismatch>
|
||||
</file>
|
||||
<file src="src/Views/Engines/PhpEngine.php">
|
||||
<ParamNameMismatch occurrences="1">
|
||||
<code>$baseException</code>
|
||||
</ParamNameMismatch>
|
||||
</file>
|
||||
</files>
|
||||
47
vendor/facade/ignition/psalm.xml
vendored
Normal file
47
vendor/facade/ignition/psalm.xml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="4"
|
||||
findUnusedVariablesAndParams="true"
|
||||
resolveFromConfigFile="true"
|
||||
useDocblockPropertyTypes="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
errorBaseline="psalm-baseline.xml"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src"/>
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<UndefinedInterfaceMethod>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/Solutions/SolutionTransformer.php" />
|
||||
</errorLevel>
|
||||
</UndefinedInterfaceMethod>
|
||||
<ForbiddenCode>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/SolutionProviders/MergeConflictSolutionProvider.php" />
|
||||
</errorLevel>
|
||||
</ForbiddenCode>
|
||||
<InvalidCast>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/DumpRecorder/DumpRecorder.php" />
|
||||
</errorLevel>
|
||||
</InvalidCast>
|
||||
<UndefinedClass>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/ErrorPage/ErrorPageViewModel.php" />
|
||||
<file name="src/ErrorPage/IgnitionExceptionRenderer.php" />
|
||||
<file name="src/IgnitionServiceProvider.php" />
|
||||
</errorLevel>
|
||||
</UndefinedClass>
|
||||
</issueHandlers>
|
||||
|
||||
<plugins>
|
||||
<pluginClass class="Psalm\LaravelPlugin\Plugin"/>
|
||||
</plugins>
|
||||
</psalm>
|
||||
3
vendor/facade/ignition/resources/.gitignore
vendored
Normal file
3
vendor/facade/ignition/resources/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
compiled/*
|
||||
!compiled/index.html
|
||||
!compiled/ignition.js
|
||||
32
vendor/facade/ignition/resources/compiled/ignition.js
vendored
Normal file
32
vendor/facade/ignition/resources/compiled/ignition.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
vendor/facade/ignition/resources/compiled/index.html
vendored
Normal file
12
vendor/facade/ignition/resources/compiled/index.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Vue App</title>
|
||||
<link href="/flare.js" rel="preload" as="script"></head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript" src="/flare.js"></script></body>
|
||||
</html>
|
||||
65
vendor/facade/ignition/resources/views/errorPage.php
vendored
Normal file
65
vendor/facade/ignition/resources/views/errorPage.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<!doctype html>
|
||||
<html class="theme-<?=$config['theme']?>">
|
||||
<!--
|
||||
<?=$throwableString?>
|
||||
-->
|
||||
<head>
|
||||
<!-- Hide dumps asap -->
|
||||
<style>
|
||||
pre.sf-dump {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
|
||||
<title><?= $title ?></title>
|
||||
|
||||
<?php foreach ($styles as $script): ?>
|
||||
<link rel="stylesheet" href="<?=$housekeepingEndpoint?>/styles/<?=$script?>">
|
||||
<?php endforeach; ?>
|
||||
|
||||
</head>
|
||||
<body class="scrollbar-lg">
|
||||
|
||||
<script>
|
||||
window.data = <?=
|
||||
$jsonEncode([
|
||||
'report' => $report,
|
||||
'config' => $config,
|
||||
'solutions' => $solutions,
|
||||
'telescopeUrl' => $telescopeUrl,
|
||||
'shareEndpoint' => $shareEndpoint,
|
||||
'defaultTab' => $defaultTab,
|
||||
'defaultTabProps' => $defaultTabProps,
|
||||
'appEnv' => $appEnv,
|
||||
'appDebug' => $appDebug,
|
||||
])
|
||||
?>;
|
||||
|
||||
window.tabs = <?=$tabs?>;
|
||||
</script>
|
||||
|
||||
<noscript><pre><?=$throwableString?></pre></noscript>
|
||||
|
||||
<div id="app"></div>
|
||||
|
||||
<script><?= $getAssetContents('ignition.js') ?></script>
|
||||
<script>
|
||||
window.Ignition = window.ignite(window.data);
|
||||
</script>
|
||||
<?php foreach ($scripts as $script): ?>
|
||||
<script src="<?=$housekeepingEndpoint?>/scripts/<?=$script?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<script>
|
||||
Ignition.start();
|
||||
</script>
|
||||
<!--
|
||||
<?=$throwableString?>
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
168
vendor/facade/ignition/src/Actions/ShareReportAction.php
vendored
Normal file
168
vendor/facade/ignition/src/Actions/ShareReportAction.php
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Actions;
|
||||
|
||||
use Exception;
|
||||
use Facade\FlareClient\Http\Client;
|
||||
use Facade\FlareClient\Truncation\ReportTrimmer;
|
||||
use Facade\Ignition\Exceptions\UnableToShareErrorException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ShareReportAction
|
||||
{
|
||||
/** @var array */
|
||||
protected $tabs;
|
||||
|
||||
/** @var \Facade\FlareClient\Http\Client */
|
||||
protected $client;
|
||||
|
||||
public function __construct(Client $client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function handle(array $report, array $tabs, ?string $lineSelection = null)
|
||||
{
|
||||
$this->tabs = $tabs;
|
||||
|
||||
$report = $this->filterReport($report);
|
||||
|
||||
try {
|
||||
return $this->client->post('public-reports', [
|
||||
'report' => $this->trimReport($report),
|
||||
'tabs' => $tabs,
|
||||
'lineSelection' => $lineSelection,
|
||||
]);
|
||||
} catch (Exception $exception) {
|
||||
throw new UnableToShareErrorException($exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function filterReport(array $report): array
|
||||
{
|
||||
if (! $this->hasTab('stackTraceTab')) {
|
||||
$report['stacktrace'] = array_slice($report['stacktrace'], 0, 1);
|
||||
}
|
||||
|
||||
if (! $this->hasTab('debugTab')) {
|
||||
$report['glows'] = [];
|
||||
}
|
||||
|
||||
$report['context'] = $this->filterContextItems($report['context']);
|
||||
|
||||
return $report;
|
||||
}
|
||||
|
||||
protected function hasTab(string $tab): bool
|
||||
{
|
||||
return in_array($tab, $this->tabs);
|
||||
}
|
||||
|
||||
protected function filterContextItems(array $contextItems): array
|
||||
{
|
||||
if (! $this->hasTab('requestTab')) {
|
||||
$contextItems = $this->removeRequestInformation($contextItems);
|
||||
}
|
||||
|
||||
if (! $this->hasTab('appTab')) {
|
||||
$contextItems = $this->removeAppInformation($contextItems);
|
||||
}
|
||||
|
||||
if (! $this->hasTab('userTab')) {
|
||||
$contextItems = $this->removeUserInformation($contextItems);
|
||||
}
|
||||
|
||||
if (! $this->hasTab('contextTab')) {
|
||||
$contextItems = $this->removeContextInformation($contextItems);
|
||||
}
|
||||
|
||||
if (! $this->hasTab('debugTab')) {
|
||||
$contextItems = $this->removeDebugInformation($contextItems);
|
||||
}
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function removeRequestInformation(array $contextItems): array
|
||||
{
|
||||
Arr::forget($contextItems, 'request');
|
||||
Arr::forget($contextItems, 'request_data');
|
||||
Arr::forget($contextItems, 'headers');
|
||||
Arr::forget($contextItems, 'session');
|
||||
Arr::forget($contextItems, 'cookies');
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function removeAppInformation(array $contextItems): array
|
||||
{
|
||||
Arr::forget($contextItems, 'view');
|
||||
Arr::forget($contextItems, 'route');
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function removeUserInformation(array $contextItems): array
|
||||
{
|
||||
Arr::forget($contextItems, 'user');
|
||||
Arr::forget($contextItems, 'request.ip');
|
||||
Arr::forget($contextItems, 'request.useragent');
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function removeContextInformation(array $contextItems): array
|
||||
{
|
||||
Arr::forget($contextItems, 'env');
|
||||
Arr::forget($contextItems, 'git');
|
||||
Arr::forget($contextItems, 'context');
|
||||
|
||||
Arr::forget($contextItems, $this->getCustomContextGroups($contextItems));
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function removeDebugInformation(array $contextItems): array
|
||||
{
|
||||
Arr::forget($contextItems, 'dumps');
|
||||
Arr::forget($contextItems, 'glows');
|
||||
Arr::forget($contextItems, 'logs');
|
||||
Arr::forget($contextItems, 'queries');
|
||||
|
||||
return $contextItems;
|
||||
}
|
||||
|
||||
protected function getCustomContextGroups(array $contextItems): array
|
||||
{
|
||||
$predefinedContextItemGroups = [
|
||||
'request',
|
||||
'request_data',
|
||||
'headers',
|
||||
'session',
|
||||
'cookies',
|
||||
'view',
|
||||
'queries',
|
||||
'route',
|
||||
'user',
|
||||
'env',
|
||||
'git',
|
||||
'context',
|
||||
'logs',
|
||||
'dumps',
|
||||
'exception',
|
||||
];
|
||||
|
||||
return Collection::make($contextItems)
|
||||
->reject(function ($_value, $group) use ($predefinedContextItemGroups) {
|
||||
return in_array($group, $predefinedContextItemGroups);
|
||||
})
|
||||
->keys()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
protected function trimReport(array $report): array
|
||||
{
|
||||
return (new ReportTrimmer())->trim($report);
|
||||
}
|
||||
}
|
||||
65
vendor/facade/ignition/src/Commands/SolutionMakeCommand.php
vendored
Normal file
65
vendor/facade/ignition/src/Commands/SolutionMakeCommand.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Commands;
|
||||
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
class SolutionMakeCommand extends GeneratorCommand
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'ignition:make-solution';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new custom Ignition solution class';
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'Solution';
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return $this->option('runnable')
|
||||
? __DIR__.'/stubs/runnable-solution.stub'
|
||||
: __DIR__.'/stubs/solution.stub';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace.'\Solutions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [
|
||||
['runnable', null, InputOption::VALUE_NONE, 'Create runnable solution'],
|
||||
];
|
||||
}
|
||||
}
|
||||
50
vendor/facade/ignition/src/Commands/SolutionProviderMakeCommand.php
vendored
Normal file
50
vendor/facade/ignition/src/Commands/SolutionProviderMakeCommand.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Commands;
|
||||
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
|
||||
class SolutionProviderMakeCommand extends GeneratorCommand
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'ignition:make-solution-provider';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new custom Ignition solution provider class';
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'Solution Provider';
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__.'/stubs/solution-provider.stub';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace.'\SolutionProviders';
|
||||
}
|
||||
}
|
||||
125
vendor/facade/ignition/src/Commands/TestCommand.php
vendored
Normal file
125
vendor/facade/ignition/src/Commands/TestCommand.php
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Commands;
|
||||
|
||||
use Composer\InstalledVersions;
|
||||
use Exception;
|
||||
use Facade\FlareClient\Flare;
|
||||
use Facade\FlareClient\Http\Exceptions\BadResponseCode;
|
||||
use Illuminate\Config\Repository;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Log\LogManager;
|
||||
|
||||
class TestCommand extends Command
|
||||
{
|
||||
protected $signature = 'flare:test';
|
||||
|
||||
protected $description = 'Send a test notification to Flare';
|
||||
|
||||
/** @var \Illuminate\Config\Repository */
|
||||
protected $config;
|
||||
|
||||
public function handle(Repository $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
$this->checkFlareKey();
|
||||
|
||||
if (app()->make('log') instanceof LogManager) {
|
||||
$this->checkFlareLogger();
|
||||
}
|
||||
|
||||
$this->sendTestException();
|
||||
}
|
||||
|
||||
protected function checkFlareKey()
|
||||
{
|
||||
$message = empty($this->config->get('flare.key'))
|
||||
? '❌ Flare key not specified. Make sure you specify a value in the `key` key of the `flare` config file.'
|
||||
: '✅ Flare key specified';
|
||||
|
||||
$this->info($message);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function checkFlareLogger()
|
||||
{
|
||||
$defaultLogChannel = $this->config->get('logging.default');
|
||||
|
||||
$activeStack = $this->config->get("logging.channels.{$defaultLogChannel}");
|
||||
|
||||
if (is_null($activeStack)) {
|
||||
$this->info("❌ The default logging channel `{$defaultLogChannel}` is not configured in the `logging` config file");
|
||||
}
|
||||
|
||||
if (! isset($activeStack['channels']) || ! in_array('flare', $activeStack['channels'])) {
|
||||
$this->info("❌ The logging channel `{$defaultLogChannel}` does not contain the 'flare' channel");
|
||||
}
|
||||
|
||||
if (is_null($this->config->get('logging.channels.flare'))) {
|
||||
$this->info('❌ There is no logging channel named `flare` in the `logging` config file');
|
||||
}
|
||||
|
||||
if ($this->config->get('logging.channels.flare.driver') !== 'flare') {
|
||||
$this->info('❌ The `flare` logging channel defined in the `logging` config file is not set to `flare`.');
|
||||
}
|
||||
|
||||
$this->info('✅ The Flare logging driver was configured correctly.');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function sendTestException()
|
||||
{
|
||||
$testException = new Exception('This is an exception to test if the integration with Flare works.');
|
||||
|
||||
try {
|
||||
app(Flare::class)->sendTestReport($testException);
|
||||
$this->info('');
|
||||
} catch (Exception $exception) {
|
||||
$this->warn('❌ We were unable to send an exception to Flare. ');
|
||||
|
||||
if ($exception instanceof BadResponseCode) {
|
||||
$this->info('');
|
||||
$message = 'Unknown error';
|
||||
|
||||
$body = $exception->response->getBody();
|
||||
|
||||
if (is_array($body) && isset($body['message'])) {
|
||||
$message = $body['message'];
|
||||
}
|
||||
|
||||
$this->warn("{$exception->response->getHttpResponseCode()} - {$message}");
|
||||
} else {
|
||||
$this->warn($exception->getMessage());
|
||||
}
|
||||
|
||||
$this->warn('Make sure that your key is correct and that you have a valid subscription.');
|
||||
$this->info('');
|
||||
$this->info('For more info visit the docs on https://flareapp.io/docs/ignition-for-laravel/introduction');
|
||||
$this->info('You can see the status page of Flare at https://status.flareapp.io');
|
||||
$this->info('Flare support can be reached at support@flareapp.io');
|
||||
|
||||
$this->line('');
|
||||
$this->line('Extra info');
|
||||
$this->table([], [
|
||||
['Platform', PHP_OS],
|
||||
['PHP', phpversion()],
|
||||
['Laravel', app()->version()],
|
||||
['facade/ignition', InstalledVersions::getVersion('facade/ignition')],
|
||||
['facade/flare-client-php', InstalledVersions::getVersion('facade/flare-client-php')],
|
||||
['Curl', curl_version()['version']],
|
||||
['SSL', curl_version()['ssl_version']],
|
||||
]);
|
||||
|
||||
if ($this->output->isVerbose()) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->info('We tried to send an exception to Flare. Please check if it arrived!');
|
||||
}
|
||||
}
|
||||
43
vendor/facade/ignition/src/Commands/stubs/runnable-solution.stub
vendored
Normal file
43
vendor/facade/ignition/src/Commands/stubs/runnable-solution.stub
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
|
||||
class DummyClass implements RunnableSolution
|
||||
{
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionActionDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getRunButtonText(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getRunParameters(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function run(array $parameters = [])
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
18
vendor/facade/ignition/src/Commands/stubs/solution-provider.stub
vendored
Normal file
18
vendor/facade/ignition/src/Commands/stubs/solution-provider.stub
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
|
||||
class DummyClass implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getSolutions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
23
vendor/facade/ignition/src/Commands/stubs/solution.stub
vendored
Normal file
23
vendor/facade/ignition/src/Commands/stubs/solution.stub
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class DummyClass implements Solution
|
||||
{
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
9
vendor/facade/ignition/src/Context/LaravelConsoleContext.php
vendored
Normal file
9
vendor/facade/ignition/src/Context/LaravelConsoleContext.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Context;
|
||||
|
||||
use Facade\FlareClient\Context\ConsoleContext;
|
||||
|
||||
class LaravelConsoleContext extends ConsoleContext
|
||||
{
|
||||
}
|
||||
31
vendor/facade/ignition/src/Context/LaravelContextDetector.php
vendored
Normal file
31
vendor/facade/ignition/src/Context/LaravelContextDetector.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Context;
|
||||
|
||||
use Facade\FlareClient\Context\ContextDetectorInterface;
|
||||
use Facade\FlareClient\Context\ContextInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Livewire\LivewireManager;
|
||||
|
||||
class LaravelContextDetector implements ContextDetectorInterface
|
||||
{
|
||||
public function detectCurrentContext(): ContextInterface
|
||||
{
|
||||
if (app()->runningInConsole()) {
|
||||
return new LaravelConsoleContext($_SERVER['argv'] ?? []);
|
||||
}
|
||||
|
||||
$request = app(Request::class);
|
||||
|
||||
if ($this->isRunningLiveWire($request)) {
|
||||
return new LivewireRequestContext($request, app(LivewireManager::class));
|
||||
}
|
||||
|
||||
return new LaravelRequestContext($request);
|
||||
}
|
||||
|
||||
protected function isRunningLiveWire(Request $request)
|
||||
{
|
||||
return $request->hasHeader('x-livewire') && $request->hasHeader('referer');
|
||||
}
|
||||
}
|
||||
85
vendor/facade/ignition/src/Context/LaravelRequestContext.php
vendored
Normal file
85
vendor/facade/ignition/src/Context/LaravelRequestContext.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Context;
|
||||
|
||||
use Facade\FlareClient\Context\RequestContext;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Throwable;
|
||||
|
||||
class LaravelRequestContext extends RequestContext
|
||||
{
|
||||
/** @var \Illuminate\Http\Request */
|
||||
protected $request;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function getUser(): array
|
||||
{
|
||||
try {
|
||||
$user = $this->request->user();
|
||||
|
||||
if (! $user) {
|
||||
return [];
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
if (method_exists($user, 'toFlare')) {
|
||||
return $user->toFlare();
|
||||
}
|
||||
|
||||
if (method_exists($user, 'toArray')) {
|
||||
return $user->toArray();
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getRoute(): array
|
||||
{
|
||||
$route = $this->request->route();
|
||||
|
||||
return [
|
||||
'route' => optional($route)->getName(),
|
||||
'routeParameters' => $this->getRouteParameters(),
|
||||
'controllerAction' => optional($route)->getActionName(),
|
||||
'middleware' => array_values(optional($route)->gatherMiddleware() ?? []),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRouteParameters(): array
|
||||
{
|
||||
try {
|
||||
return collect(optional($this->request->route())->parameters ?? [])
|
||||
->map(function ($parameter) {
|
||||
return $parameter instanceof Model ? $parameter->withoutRelations() : $parameter;
|
||||
})
|
||||
->map(function ($parameter) {
|
||||
return method_exists($parameter, 'toFlare') ? $parameter->toFlare() : $parameter;
|
||||
})
|
||||
->toArray();
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$properties = parent::toArray();
|
||||
|
||||
$properties['route'] = $this->getRoute();
|
||||
|
||||
$properties['user'] = $this->getUser();
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
94
vendor/facade/ignition/src/Context/LivewireRequestContext.php
vendored
Normal file
94
vendor/facade/ignition/src/Context/LivewireRequestContext.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Context;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Livewire\LivewireManager;
|
||||
|
||||
class LivewireRequestContext extends LaravelRequestContext
|
||||
{
|
||||
/** @var \Livewire\LivewireManager */
|
||||
protected $livewireManager;
|
||||
|
||||
public function __construct(
|
||||
Request $request,
|
||||
LivewireManager $livewireManager
|
||||
) {
|
||||
parent::__construct($request);
|
||||
|
||||
$this->livewireManager = $livewireManager;
|
||||
}
|
||||
|
||||
public function getRequest(): array
|
||||
{
|
||||
$properties = parent::getRequest();
|
||||
|
||||
$properties['method'] = $this->livewireManager->originalMethod();
|
||||
$properties['url'] = $this->livewireManager->originalUrl();
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$properties = parent::toArray();
|
||||
|
||||
$properties['livewire'] = $this->getLiveWireInformation();
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
protected function getLiveWireInformation(): array
|
||||
{
|
||||
$componentId = $this->request->input('fingerprint.id');
|
||||
$componentAlias = $this->request->input('fingerprint.name');
|
||||
|
||||
if ($componentAlias === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$componentClass = $this->livewireManager->getClass($componentAlias);
|
||||
} catch (Exception $e) {
|
||||
$componentClass = null;
|
||||
}
|
||||
|
||||
return [
|
||||
'component_class' => $componentClass,
|
||||
'component_alias' => $componentAlias,
|
||||
'component_id' => $componentId,
|
||||
'data' => $this->resolveData(),
|
||||
'updates' => $this->resolveUpdates(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function resolveData(): array
|
||||
{
|
||||
$data = $this->request->input('serverMemo.data') ?? [];
|
||||
|
||||
$dataMeta = $this->request->input('serverMemo.dataMeta') ?? [];
|
||||
|
||||
foreach ($dataMeta['modelCollections'] ?? [] as $key => $value) {
|
||||
$data[$key] = array_merge($data[$key] ?? [], $value);
|
||||
}
|
||||
|
||||
foreach ($dataMeta['models'] ?? [] as $key => $value) {
|
||||
$data[$key] = array_merge($data[$key] ?? [], $value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function resolveUpdates()
|
||||
{
|
||||
$updates = $this->request->input('updates') ?? [];
|
||||
|
||||
return array_map(function (array $update) {
|
||||
$update['payload'] = Arr::except($update['payload'] ?? [], ['id']);
|
||||
|
||||
return $update;
|
||||
}, $updates);
|
||||
}
|
||||
}
|
||||
36
vendor/facade/ignition/src/DumpRecorder/Dump.php
vendored
Normal file
36
vendor/facade/ignition/src/DumpRecorder/Dump.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\DumpRecorder;
|
||||
|
||||
class Dump
|
||||
{
|
||||
/** @var string */
|
||||
protected $htmlDump;
|
||||
|
||||
/** @var ?string */
|
||||
protected $file;
|
||||
|
||||
/** @var ?int */
|
||||
protected $lineNumber;
|
||||
|
||||
/** @var float */
|
||||
protected $microtime;
|
||||
|
||||
public function __construct(string $htmlDump, ?string $file, ?int $lineNumber, ?float $microtime = null)
|
||||
{
|
||||
$this->htmlDump = $htmlDump;
|
||||
$this->file = $file;
|
||||
$this->lineNumber = $lineNumber;
|
||||
$this->microtime = $microtime ?? microtime(true);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'html_dump' => $this->htmlDump,
|
||||
'file' => $this->file,
|
||||
'line_number' => $this->lineNumber,
|
||||
'microtime' => $this->microtime,
|
||||
];
|
||||
}
|
||||
}
|
||||
23
vendor/facade/ignition/src/DumpRecorder/DumpHandler.php
vendored
Normal file
23
vendor/facade/ignition/src/DumpRecorder/DumpHandler.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\DumpRecorder;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
|
||||
class DumpHandler
|
||||
{
|
||||
/** @var \Facade\Ignition\DumpRecorder\DumpRecorder */
|
||||
protected $dumpRecorder;
|
||||
|
||||
public function __construct(DumpRecorder $dumpRecorder)
|
||||
{
|
||||
$this->dumpRecorder = $dumpRecorder;
|
||||
}
|
||||
|
||||
public function dump($value)
|
||||
{
|
||||
$data = (new VarCloner())->cloneVar($value);
|
||||
|
||||
$this->dumpRecorder->record($data);
|
||||
}
|
||||
}
|
||||
112
vendor/facade/ignition/src/DumpRecorder/DumpRecorder.php
vendored
Normal file
112
vendor/facade/ignition/src/DumpRecorder/DumpRecorder.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\DumpRecorder;
|
||||
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Support\Arr;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
use Symfony\Component\VarDumper\Dumper\HtmlDumper as BaseHtmlDumper;
|
||||
use Symfony\Component\VarDumper\VarDumper;
|
||||
|
||||
class DumpRecorder
|
||||
{
|
||||
protected $dumps = [];
|
||||
|
||||
/** @var \Illuminate\Contracts\Foundation\Application */
|
||||
protected $app;
|
||||
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
public function register(): self
|
||||
{
|
||||
$multiDumpHandler = new MultiDumpHandler();
|
||||
|
||||
$this->app->singleton(MultiDumpHandler::class, function () use ($multiDumpHandler) {
|
||||
return $multiDumpHandler;
|
||||
});
|
||||
|
||||
$previousHandler = VarDumper::setHandler(function ($var) use ($multiDumpHandler) {
|
||||
$multiDumpHandler->dump($var);
|
||||
});
|
||||
|
||||
if ($previousHandler) {
|
||||
$multiDumpHandler->addHandler($previousHandler);
|
||||
} else {
|
||||
$multiDumpHandler->addHandler($this->getDefaultHandler());
|
||||
}
|
||||
|
||||
$multiDumpHandler->addHandler(function ($var) {
|
||||
(new DumpHandler($this))->dump($var);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function record(Data $data)
|
||||
{
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 8);
|
||||
$file = (string)Arr::get($backtrace, '6.file');
|
||||
$lineNumber = (int)Arr::get($backtrace, '6.line');
|
||||
|
||||
if (! Arr::exists($backtrace, '7.class') && (string)Arr::get($backtrace, '7.function') === 'ddd') {
|
||||
$file = (string)Arr::get($backtrace, '7.file');
|
||||
$lineNumber = (int)Arr::get($backtrace, '7.line');
|
||||
}
|
||||
|
||||
$htmlDump = (new HtmlDumper())->dump($data);
|
||||
|
||||
$this->dumps[] = new Dump($htmlDump, $file, $lineNumber);
|
||||
}
|
||||
|
||||
public function getDumps(): array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->dumps = [];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$dumps = [];
|
||||
|
||||
foreach ($this->dumps as $dump) {
|
||||
$dumps[] = $dump->toArray();
|
||||
}
|
||||
|
||||
return $dumps;
|
||||
}
|
||||
|
||||
protected function getDefaultHandler()
|
||||
{
|
||||
return function ($value) {
|
||||
$data = (new VarCloner())->cloneVar($value);
|
||||
|
||||
$this->getDumper()->dump($data);
|
||||
};
|
||||
}
|
||||
|
||||
protected function getDumper()
|
||||
{
|
||||
if (isset($_SERVER['VAR_DUMPER_FORMAT'])) {
|
||||
if ($_SERVER['VAR_DUMPER_FORMAT'] === 'html') {
|
||||
return new BaseHtmlDumper();
|
||||
}
|
||||
|
||||
return new CliDumper();
|
||||
}
|
||||
|
||||
if (in_array(PHP_SAPI, ['cli', 'phpdbg']) && ! isset($_SERVER['LARAVEL_OCTANE'])) {
|
||||
return new CliDumper() ;
|
||||
}
|
||||
|
||||
return new BaseHtmlDumper();
|
||||
}
|
||||
}
|
||||
29
vendor/facade/ignition/src/DumpRecorder/HtmlDumper.php
vendored
Normal file
29
vendor/facade/ignition/src/DumpRecorder/HtmlDumper.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\DumpRecorder;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\HtmlDumper as BaseHtmlDumper;
|
||||
|
||||
class HtmlDumper extends BaseHtmlDumper
|
||||
{
|
||||
protected $dumpHeader = '';
|
||||
|
||||
public function dumpVariable($variable): string
|
||||
{
|
||||
$cloner = new VarCloner();
|
||||
|
||||
$clonedData = $cloner->cloneVar($variable)->withMaxDepth(3);
|
||||
|
||||
return $this->dump($clonedData);
|
||||
}
|
||||
|
||||
public function dump(Data $data, $output = null, array $extraDisplayOptions = []): string
|
||||
{
|
||||
return (string)parent::dump($data, true, [
|
||||
'maxDepth' => 3,
|
||||
'maxStringLength' => 160,
|
||||
]);
|
||||
}
|
||||
}
|
||||
23
vendor/facade/ignition/src/DumpRecorder/MultiDumpHandler.php
vendored
Normal file
23
vendor/facade/ignition/src/DumpRecorder/MultiDumpHandler.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\DumpRecorder;
|
||||
|
||||
class MultiDumpHandler
|
||||
{
|
||||
/** @var array */
|
||||
protected $handlers = [];
|
||||
|
||||
public function dump($value)
|
||||
{
|
||||
foreach ($this->handlers as $handler) {
|
||||
$handler($value);
|
||||
}
|
||||
}
|
||||
|
||||
public function addHandler(callable $callable = null): self
|
||||
{
|
||||
$this->handlers[] = $callable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
77
vendor/facade/ignition/src/ErrorPage/ErrorPageHandler.php
vendored
Normal file
77
vendor/facade/ignition/src/ErrorPage/ErrorPageHandler.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\ErrorPage;
|
||||
|
||||
use Facade\FlareClient\Flare;
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\IgnitionConfig;
|
||||
use Facade\IgnitionContracts\SolutionProviderRepository;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Throwable;
|
||||
|
||||
class ErrorPageHandler
|
||||
{
|
||||
/** @var \Facade\Ignition\IgnitionConfig */
|
||||
protected $ignitionConfig;
|
||||
|
||||
/** @var \Facade\FlareClient\Flare */
|
||||
protected $flareClient;
|
||||
|
||||
/** @var \Facade\Ignition\ErrorPage\Renderer */
|
||||
protected $renderer;
|
||||
|
||||
/** @var \Facade\IgnitionContracts\SolutionProviderRepository */
|
||||
protected $solutionProviderRepository;
|
||||
|
||||
public function __construct(
|
||||
Application $app,
|
||||
IgnitionConfig $ignitionConfig,
|
||||
Renderer $renderer,
|
||||
SolutionProviderRepository $solutionProviderRepository
|
||||
) {
|
||||
$this->flareClient = $app->make(Flare::class);
|
||||
$this->ignitionConfig = $ignitionConfig;
|
||||
$this->renderer = $renderer;
|
||||
$this->solutionProviderRepository = $solutionProviderRepository;
|
||||
}
|
||||
|
||||
public function handle(Throwable $throwable, $defaultTab = null, $defaultTabProps = [])
|
||||
{
|
||||
$report = $this->flareClient->createReport($throwable);
|
||||
|
||||
$solutions = $this->solutionProviderRepository->getSolutionsForThrowable($throwable);
|
||||
|
||||
$viewModel = new ErrorPageViewModel(
|
||||
$throwable,
|
||||
$this->ignitionConfig,
|
||||
$report,
|
||||
$solutions
|
||||
);
|
||||
|
||||
$viewModel->defaultTab($defaultTab, $defaultTabProps);
|
||||
|
||||
$this->renderException($viewModel);
|
||||
}
|
||||
|
||||
public function handleReport(Report $report, $defaultTab = null, $defaultTabProps = [])
|
||||
{
|
||||
$viewModel = new ErrorPageViewModel(
|
||||
$report->getThrowable(),
|
||||
$this->ignitionConfig,
|
||||
$report,
|
||||
[]
|
||||
);
|
||||
|
||||
$viewModel->defaultTab($defaultTab, $defaultTabProps);
|
||||
|
||||
$this->renderException($viewModel);
|
||||
}
|
||||
|
||||
protected function renderException(ErrorPageViewModel $exceptionViewModel)
|
||||
{
|
||||
echo $this->renderer->render(
|
||||
'errorPage',
|
||||
$exceptionViewModel->toArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
200
vendor/facade/ignition/src/ErrorPage/ErrorPageViewModel.php
vendored
Normal file
200
vendor/facade/ignition/src/ErrorPage/ErrorPageViewModel.php
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\ErrorPage;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\Ignition;
|
||||
use Facade\Ignition\IgnitionConfig;
|
||||
use Facade\Ignition\Solutions\SolutionTransformer;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Laravel\Telescope\Http\Controllers\HomeController;
|
||||
use Laravel\Telescope\IncomingExceptionEntry;
|
||||
use Laravel\Telescope\Telescope;
|
||||
use Throwable;
|
||||
|
||||
class ErrorPageViewModel implements Arrayable
|
||||
{
|
||||
/** @var \Throwable|null */
|
||||
protected $throwable;
|
||||
|
||||
/** @var array */
|
||||
protected $solutions;
|
||||
|
||||
/** @var \Facade\Ignition\IgnitionConfig */
|
||||
protected $ignitionConfig;
|
||||
|
||||
/** @var \Facade\FlareClient\Report */
|
||||
protected $report;
|
||||
|
||||
/** @var string */
|
||||
protected $defaultTab;
|
||||
|
||||
/** @var array */
|
||||
protected $defaultTabProps = [];
|
||||
|
||||
/** @var string */
|
||||
protected $appEnv;
|
||||
|
||||
/** @var bool */
|
||||
protected $appDebug;
|
||||
|
||||
public function __construct(?Throwable $throwable, IgnitionConfig $ignitionConfig, Report $report, array $solutions)
|
||||
{
|
||||
$this->throwable = $throwable;
|
||||
|
||||
$this->ignitionConfig = $ignitionConfig;
|
||||
|
||||
$this->report = $report;
|
||||
|
||||
$this->solutions = $solutions;
|
||||
|
||||
$this->appEnv = config('app.env');
|
||||
$this->appDebug = config('app.debug');
|
||||
}
|
||||
|
||||
public function throwableString(): string
|
||||
{
|
||||
if (! $this->throwable) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$throwableString = sprintf(
|
||||
"%s: %s in file %s on line %d\n\n%s\n",
|
||||
get_class($this->throwable),
|
||||
$this->throwable->getMessage(),
|
||||
$this->throwable->getFile(),
|
||||
$this->throwable->getLine(),
|
||||
$this->report->getThrowable()->getTraceAsString()
|
||||
);
|
||||
|
||||
return htmlspecialchars($throwableString);
|
||||
}
|
||||
|
||||
public function telescopeUrl(): ?string
|
||||
{
|
||||
try {
|
||||
if (! class_exists(Telescope::class)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! count(Telescope::$entriesQueue)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$telescopeEntry = collect(Telescope::$entriesQueue)->first(function ($entry) {
|
||||
return $entry instanceof IncomingExceptionEntry;
|
||||
});
|
||||
|
||||
if (is_null($telescopeEntry)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$telescopeEntryId = (string) $telescopeEntry->uuid;
|
||||
|
||||
return url(action([HomeController::class, 'index'])."/exceptions/{$telescopeEntryId}");
|
||||
} catch (Exception $exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function title(): string
|
||||
{
|
||||
$message = htmlspecialchars($this->report->getMessage());
|
||||
|
||||
return "🧨 {$message}";
|
||||
}
|
||||
|
||||
public function config(): array
|
||||
{
|
||||
return $this->ignitionConfig->toArray();
|
||||
}
|
||||
|
||||
public function solutions(): array
|
||||
{
|
||||
$solutions = [];
|
||||
|
||||
foreach ($this->solutions as $solution) {
|
||||
$solutions[] = (new SolutionTransformer($solution))->toArray();
|
||||
}
|
||||
|
||||
return $solutions;
|
||||
}
|
||||
|
||||
protected function shareEndpoint(): string
|
||||
{
|
||||
try {
|
||||
// use string notation as L5.5 and L5.6 don't support array notation yet
|
||||
return action('\Facade\Ignition\Http\Controllers\ShareReportController');
|
||||
} catch (Exception $exception) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function report(): array
|
||||
{
|
||||
return $this->report->toArray();
|
||||
}
|
||||
|
||||
public function jsonEncode($data): string
|
||||
{
|
||||
$jsonOptions = JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;
|
||||
|
||||
return json_encode($data, $jsonOptions);
|
||||
}
|
||||
|
||||
public function getAssetContents(string $asset): string
|
||||
{
|
||||
$assetPath = __DIR__."/../../resources/compiled/{$asset}";
|
||||
|
||||
return file_get_contents($assetPath);
|
||||
}
|
||||
|
||||
public function styles(): array
|
||||
{
|
||||
return array_keys(Ignition::styles());
|
||||
}
|
||||
|
||||
public function scripts(): array
|
||||
{
|
||||
return array_keys(Ignition::scripts());
|
||||
}
|
||||
|
||||
public function tabs(): string
|
||||
{
|
||||
return json_encode(Ignition::$tabs);
|
||||
}
|
||||
|
||||
public function defaultTab(?string $defaultTab, ?array $defaultTabProps)
|
||||
{
|
||||
$this->defaultTab = $defaultTab ?? 'StackTab';
|
||||
|
||||
if ($defaultTabProps) {
|
||||
$this->defaultTabProps = $defaultTabProps;
|
||||
}
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'throwableString' => $this->throwableString(),
|
||||
'telescopeUrl' => $this->telescopeUrl(),
|
||||
'shareEndpoint' => $this->shareEndpoint(),
|
||||
'title' => $this->title(),
|
||||
'config' => $this->config(),
|
||||
'solutions' => $this->solutions(),
|
||||
'report' => $this->report(),
|
||||
'housekeepingEndpoint' => url(config('ignition.housekeeping_endpoint_prefix', '_ignition')),
|
||||
'styles' => $this->styles(),
|
||||
'scripts' => $this->scripts(),
|
||||
'tabs' => $this->tabs(),
|
||||
'jsonEncode' => Closure::fromCallable([$this, 'jsonEncode']),
|
||||
'getAssetContents' => Closure::fromCallable([$this, 'getAssetContents']),
|
||||
'defaultTab' => $this->defaultTab,
|
||||
'defaultTabProps' => $this->defaultTabProps,
|
||||
'appEnv' => $this->appEnv,
|
||||
'appDebug' => $this->appDebug,
|
||||
];
|
||||
}
|
||||
}
|
||||
26
vendor/facade/ignition/src/ErrorPage/IgnitionExceptionRenderer.php
vendored
Normal file
26
vendor/facade/ignition/src/ErrorPage/IgnitionExceptionRenderer.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\ErrorPage;
|
||||
|
||||
use Illuminate\Contracts\Foundation\ExceptionRenderer;
|
||||
|
||||
/** @psalm-suppress UndefinedClass */
|
||||
class IgnitionExceptionRenderer implements ExceptionRenderer
|
||||
{
|
||||
/** @var \Facade\Ignition\ErrorPage\ErrorPageHandler */
|
||||
protected $errorPageHandler;
|
||||
|
||||
public function __construct(ErrorPageHandler $errorPageHandler)
|
||||
{
|
||||
$this->errorPageHandler = $errorPageHandler;
|
||||
}
|
||||
|
||||
public function render($throwable)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
$this->errorPageHandler->handle($throwable);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
48
vendor/facade/ignition/src/ErrorPage/IgnitionWhoopsHandler.php
vendored
Normal file
48
vendor/facade/ignition/src/ErrorPage/IgnitionWhoopsHandler.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\ErrorPage;
|
||||
|
||||
use Error;
|
||||
use ErrorException;
|
||||
use Whoops\Handler\Handler;
|
||||
|
||||
class IgnitionWhoopsHandler extends Handler
|
||||
{
|
||||
/** @var \Facade\Ignition\ErrorPage\ErrorPageHandler */
|
||||
protected $errorPageHandler;
|
||||
|
||||
/** @var \Throwable */
|
||||
protected $exception;
|
||||
|
||||
public function __construct(ErrorPageHandler $errorPageHandler)
|
||||
{
|
||||
$this->errorPageHandler = $errorPageHandler;
|
||||
}
|
||||
|
||||
public function handle(): ?int
|
||||
{
|
||||
try {
|
||||
$this->errorPageHandler->handle($this->exception);
|
||||
} catch (Error $error) {
|
||||
// Errors aren't caught by Whoops.
|
||||
// Convert the error to an exception and throw again.
|
||||
|
||||
throw new ErrorException(
|
||||
$error->getMessage(),
|
||||
$error->getCode(),
|
||||
1,
|
||||
$error->getFile(),
|
||||
$error->getLine(),
|
||||
$error
|
||||
);
|
||||
}
|
||||
|
||||
return Handler::QUIT;
|
||||
}
|
||||
|
||||
/** @param \Throwable $exception */
|
||||
public function setException($exception): void
|
||||
{
|
||||
$this->exception = $exception;
|
||||
}
|
||||
}
|
||||
43
vendor/facade/ignition/src/ErrorPage/Renderer.php
vendored
Normal file
43
vendor/facade/ignition/src/ErrorPage/Renderer.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\ErrorPage;
|
||||
|
||||
use Exception;
|
||||
use Facade\Ignition\Exceptions\ViewException;
|
||||
|
||||
class Renderer
|
||||
{
|
||||
/** @var string */
|
||||
protected $viewPath;
|
||||
|
||||
public function __construct(string $viewPath)
|
||||
{
|
||||
$this->viewPath = $this->formatPath($viewPath);
|
||||
}
|
||||
|
||||
public function render(string $viewName, array $_data): string
|
||||
{
|
||||
ob_start();
|
||||
|
||||
$viewFile = "{$this->viewPath}/{$viewName}.php";
|
||||
|
||||
try {
|
||||
extract($_data, EXTR_OVERWRITE);
|
||||
|
||||
include $viewFile;
|
||||
} catch (Exception $exception) {
|
||||
$viewException = new ViewException($exception->getMessage());
|
||||
$viewException->setView($viewFile);
|
||||
$viewException->setViewData($_data);
|
||||
|
||||
throw $viewException;
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
protected function formatPath(string $path): string
|
||||
{
|
||||
return preg_replace('/(?:\/)+$/u', '', $path).'/';
|
||||
}
|
||||
}
|
||||
29
vendor/facade/ignition/src/Exceptions/InvalidConfig.php
vendored
Normal file
29
vendor/facade/ignition/src/Exceptions/InvalidConfig.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\ProvidesSolution;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
use Monolog\Logger;
|
||||
|
||||
class InvalidConfig extends Exception implements ProvidesSolution
|
||||
{
|
||||
public static function invalidLogLevel(string $logLevel)
|
||||
{
|
||||
return new static("Invalid log level `{$logLevel}` specified.");
|
||||
}
|
||||
|
||||
public function getSolution(): Solution
|
||||
{
|
||||
$validLogLevels = array_map(function (string $level) {
|
||||
return strtolower($level);
|
||||
}, array_keys(Logger::getLevels()));
|
||||
|
||||
$validLogLevelsString = implode(',', $validLogLevels);
|
||||
|
||||
return BaseSolution::create('You provided an invalid log level')
|
||||
->setSolutionDescription("Please change the log level in your `config/logging.php` file. Valid log levels are {$validLogLevelsString}.");
|
||||
}
|
||||
}
|
||||
9
vendor/facade/ignition/src/Exceptions/UnableToShareErrorException.php
vendored
Normal file
9
vendor/facade/ignition/src/Exceptions/UnableToShareErrorException.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class UnableToShareErrorException extends Exception
|
||||
{
|
||||
}
|
||||
51
vendor/facade/ignition/src/Exceptions/ViewException.php
vendored
Normal file
51
vendor/facade/ignition/src/Exceptions/ViewException.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Exceptions;
|
||||
|
||||
use ErrorException;
|
||||
use Facade\FlareClient\Contracts\ProvidesFlareContext;
|
||||
use Facade\Ignition\DumpRecorder\HtmlDumper;
|
||||
|
||||
class ViewException extends ErrorException implements ProvidesFlareContext
|
||||
{
|
||||
/** @var array */
|
||||
protected $viewData = [];
|
||||
|
||||
/** @var string */
|
||||
protected $view = '';
|
||||
|
||||
public function setViewData(array $data)
|
||||
{
|
||||
$this->viewData = $data;
|
||||
}
|
||||
|
||||
public function getViewData(): array
|
||||
{
|
||||
return $this->viewData;
|
||||
}
|
||||
|
||||
public function setView(string $path)
|
||||
{
|
||||
$this->view = $path;
|
||||
}
|
||||
|
||||
protected function dumpViewData($variable): string
|
||||
{
|
||||
return (new HtmlDumper())->dumpVariable($variable);
|
||||
}
|
||||
|
||||
public function context(): array
|
||||
{
|
||||
$context = [
|
||||
'view' => [
|
||||
'view' => $this->view,
|
||||
],
|
||||
];
|
||||
|
||||
if (config('flare.reporting.report_view_data')) {
|
||||
$context['view']['data'] = array_map([$this, 'dumpViewData'], $this->viewData);
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
}
|
||||
22
vendor/facade/ignition/src/Exceptions/ViewExceptionWithSolution.php
vendored
Normal file
22
vendor/facade/ignition/src/Exceptions/ViewExceptionWithSolution.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Exceptions;
|
||||
|
||||
use Facade\IgnitionContracts\ProvidesSolution;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class ViewExceptionWithSolution extends ViewException implements ProvidesSolution
|
||||
{
|
||||
/** @var Solution */
|
||||
protected $solution;
|
||||
|
||||
public function setSolution(Solution $solution)
|
||||
{
|
||||
$this->solution = $solution;
|
||||
}
|
||||
|
||||
public function getSolution(): Solution
|
||||
{
|
||||
return $this->solution;
|
||||
}
|
||||
}
|
||||
28
vendor/facade/ignition/src/Facades/Flare.php
vendored
Normal file
28
vendor/facade/ignition/src/Facades/Flare.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Facades;
|
||||
|
||||
use Facade\Ignition\Support\SentReports;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Flare.
|
||||
*
|
||||
* @method static void glow(string $name, string $messageLevel = \Facade\FlareClient\Enums\MessageLevels::INFO, array $metaData = [])
|
||||
* @method static void context($key, $value)
|
||||
* @method static void group(string $groupName, array $properties)
|
||||
*
|
||||
* @see \Facade\FlareClient\Flare
|
||||
*/
|
||||
class Flare extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return \Facade\FlareClient\Flare::class;
|
||||
}
|
||||
|
||||
public static function sentReports(): SentReports
|
||||
{
|
||||
return app(SentReports::class);
|
||||
}
|
||||
}
|
||||
46
vendor/facade/ignition/src/Http/Controllers/ExecuteSolutionController.php
vendored
Normal file
46
vendor/facade/ignition/src/Http/Controllers/ExecuteSolutionController.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Controllers;
|
||||
|
||||
use Facade\Ignition\Http\Requests\ExecuteSolutionRequest;
|
||||
use Facade\IgnitionContracts\SolutionProviderRepository;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
|
||||
class ExecuteSolutionController
|
||||
{
|
||||
use ValidatesRequests;
|
||||
|
||||
public function __invoke(
|
||||
ExecuteSolutionRequest $request,
|
||||
SolutionProviderRepository $solutionProviderRepository
|
||||
) {
|
||||
$this->ensureLocalEnvironment();
|
||||
$this->ensureLocalRequest();
|
||||
|
||||
$solution = $request->getRunnableSolution();
|
||||
|
||||
$solution->run($request->get('parameters', []));
|
||||
|
||||
return response('');
|
||||
}
|
||||
|
||||
public function ensureLocalEnvironment()
|
||||
{
|
||||
if (! app()->environment('local')) {
|
||||
abort(403, "Runnable solutions are disabled in non-local environments. Please make sure `APP_ENV` is set correctly. Additionally please make sure `APP_DEBUG` is set to false on ANY production environment!");
|
||||
}
|
||||
}
|
||||
|
||||
public function ensureLocalRequest()
|
||||
{
|
||||
$ipIsPublic = filter_var(
|
||||
request()->ip(),
|
||||
FILTER_VALIDATE_IP,
|
||||
FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
|
||||
);
|
||||
|
||||
if ($ipIsPublic) {
|
||||
abort(403, "Solutions can only be executed by requests from a local IP address. Please also make sure `APP_DEBUG` is set to false on ANY production environment.");
|
||||
}
|
||||
}
|
||||
}
|
||||
25
vendor/facade/ignition/src/Http/Controllers/HealthCheckController.php
vendored
Normal file
25
vendor/facade/ignition/src/Http/Controllers/HealthCheckController.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class HealthCheckController
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return [
|
||||
'can_execute_commands' => $this->canExecuteCommands(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function canExecuteCommands(): bool
|
||||
{
|
||||
Artisan::call('help', ['--version']);
|
||||
|
||||
$output = Artisan::output();
|
||||
|
||||
return Str::contains($output, app()->version());
|
||||
}
|
||||
}
|
||||
24
vendor/facade/ignition/src/Http/Controllers/ScriptController.php
vendored
Normal file
24
vendor/facade/ignition/src/Http/Controllers/ScriptController.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Controllers;
|
||||
|
||||
use Facade\Ignition\Ignition;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ScriptController
|
||||
{
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
if (! isset(Ignition::scripts()[$request->script])) {
|
||||
abort(404, 'Script not found');
|
||||
}
|
||||
|
||||
return response(
|
||||
file_get_contents(
|
||||
Ignition::scripts()[$request->script]
|
||||
),
|
||||
200,
|
||||
['Content-Type' => 'application/javascript']
|
||||
);
|
||||
}
|
||||
}
|
||||
19
vendor/facade/ignition/src/Http/Controllers/ShareReportController.php
vendored
Normal file
19
vendor/facade/ignition/src/Http/Controllers/ShareReportController.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Controllers;
|
||||
|
||||
use Facade\Ignition\Actions\ShareReportAction;
|
||||
use Facade\Ignition\Exceptions\UnableToShareErrorException;
|
||||
use Facade\Ignition\Http\Requests\ShareReportRequest;
|
||||
|
||||
class ShareReportController
|
||||
{
|
||||
public function __invoke(ShareReportRequest $request, ShareReportAction $shareReportAction)
|
||||
{
|
||||
try {
|
||||
return $shareReportAction->handle(json_decode($request->get('report'), true), $request->get('tabs'), $request->get('lineSelection'));
|
||||
} catch (UnableToShareErrorException $exception) {
|
||||
abort(500, 'Unable to share the error '.$exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
18
vendor/facade/ignition/src/Http/Controllers/StyleController.php
vendored
Normal file
18
vendor/facade/ignition/src/Http/Controllers/StyleController.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Controllers;
|
||||
|
||||
use Facade\Ignition\Ignition;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class StyleController
|
||||
{
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
return response(
|
||||
file_get_contents(Ignition::styles()[$request->style]),
|
||||
200,
|
||||
['Content-Type' => 'text/css']
|
||||
);
|
||||
}
|
||||
}
|
||||
27
vendor/facade/ignition/src/Http/Middleware/IgnitionConfigValueEnabled.php
vendored
Normal file
27
vendor/facade/ignition/src/Http/Middleware/IgnitionConfigValueEnabled.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Facade\Ignition\IgnitionConfig;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class IgnitionConfigValueEnabled
|
||||
{
|
||||
/** @var \Facade\Ignition\IgnitionConfig */
|
||||
protected $ignitionConfig;
|
||||
|
||||
public function __construct(IgnitionConfig $ignitionConfig)
|
||||
{
|
||||
$this->ignitionConfig = $ignitionConfig;
|
||||
}
|
||||
|
||||
public function handle(Request $request, Closure $next, string $value)
|
||||
{
|
||||
if (! $this->ignitionConfig->toArray()[$value]) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
30
vendor/facade/ignition/src/Http/Middleware/IgnitionEnabled.php
vendored
Normal file
30
vendor/facade/ignition/src/Http/Middleware/IgnitionEnabled.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class IgnitionEnabled
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (! $this->ignitionEnabled()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
protected function ignitionEnabled(): bool
|
||||
{
|
||||
return config('app.debug');
|
||||
}
|
||||
}
|
||||
41
vendor/facade/ignition/src/Http/Requests/ExecuteSolutionRequest.php
vendored
Normal file
41
vendor/facade/ignition/src/Http/Requests/ExecuteSolutionRequest.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Requests;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
use Facade\IgnitionContracts\SolutionProviderRepository;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ExecuteSolutionRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'solution' => 'required',
|
||||
'parameters' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
public function getSolution(): Solution
|
||||
{
|
||||
$solution = app(SolutionProviderRepository::class)
|
||||
->getSolutionForClass($this->get('solution'));
|
||||
|
||||
abort_if(is_null($solution), 404, 'Solution could not be found');
|
||||
|
||||
/** @var Solution */
|
||||
return $solution;
|
||||
}
|
||||
|
||||
public function getRunnableSolution(): RunnableSolution
|
||||
{
|
||||
$solution = $this->getSolution();
|
||||
|
||||
if (! $solution instanceof RunnableSolution) {
|
||||
abort(404, 'Runnable solution could not be found');
|
||||
}
|
||||
|
||||
return $solution;
|
||||
}
|
||||
}
|
||||
17
vendor/facade/ignition/src/Http/Requests/ShareReportRequest.php
vendored
Normal file
17
vendor/facade/ignition/src/Http/Requests/ShareReportRequest.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ShareReportRequest extends FormRequest
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'report' => 'required',
|
||||
'tabs' => 'required|array|min:1',
|
||||
'lineSelection' => [],
|
||||
];
|
||||
}
|
||||
}
|
||||
43
vendor/facade/ignition/src/Ignition.php
vendored
Normal file
43
vendor/facade/ignition/src/Ignition.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition;
|
||||
|
||||
use Closure;
|
||||
use Facade\Ignition\Tabs\Tab;
|
||||
|
||||
class Ignition
|
||||
{
|
||||
/** @var Closure[] */
|
||||
public static $callBeforeShowingErrorPage = [];
|
||||
|
||||
/** @var array */
|
||||
public static $tabs = [];
|
||||
|
||||
public static function tab(Tab $tab)
|
||||
{
|
||||
static::$tabs[] = $tab;
|
||||
}
|
||||
|
||||
public static function styles(): array
|
||||
{
|
||||
return collect(static::$tabs)->flatMap(function ($tab) {
|
||||
return $tab->styles;
|
||||
})
|
||||
->unique()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function scripts(): array
|
||||
{
|
||||
return collect(static::$tabs)->flatMap(function ($tab) {
|
||||
return $tab->scripts;
|
||||
})
|
||||
->unique()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public static function registerAssets(Closure $callable)
|
||||
{
|
||||
static::$callBeforeShowingErrorPage[] = $callable;
|
||||
}
|
||||
}
|
||||
75
vendor/facade/ignition/src/IgnitionConfig.php
vendored
Normal file
75
vendor/facade/ignition/src/IgnitionConfig.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class IgnitionConfig implements Arrayable
|
||||
{
|
||||
/** @var array */
|
||||
protected $options;
|
||||
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = $this->mergeWithDefaultConfig($options);
|
||||
}
|
||||
|
||||
public function getEditor(): ?string
|
||||
{
|
||||
return Arr::get($this->options, 'editor');
|
||||
}
|
||||
|
||||
public function getRemoteSitesPath(): ?string
|
||||
{
|
||||
return Arr::get($this->options, 'remote_sites_path');
|
||||
}
|
||||
|
||||
public function getLocalSitesPath(): ?string
|
||||
{
|
||||
return Arr::get($this->options, 'local_sites_path');
|
||||
}
|
||||
|
||||
public function getTheme(): ?string
|
||||
{
|
||||
return Arr::get($this->options, 'theme');
|
||||
}
|
||||
|
||||
public function getEnableShareButton(): bool
|
||||
{
|
||||
if (! app()->isBooted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Arr::get($this->options, 'enable_share_button', true);
|
||||
}
|
||||
|
||||
public function getEnableRunnableSolutions(): bool
|
||||
{
|
||||
$enabled = Arr::get($this->options, 'enable_runnable_solutions', null);
|
||||
|
||||
if ($enabled === null) {
|
||||
$enabled = config('app.debug');
|
||||
}
|
||||
|
||||
return $enabled ?? false;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'editor' => $this->getEditor(),
|
||||
'remoteSitesPath' => $this->getRemoteSitesPath(),
|
||||
'localSitesPath' => $this->getLocalSitesPath(),
|
||||
'theme' => $this->getTheme(),
|
||||
'enableShareButton' => $this->getEnableShareButton(),
|
||||
'enableRunnableSolutions' => $this->getEnableRunnableSolutions(),
|
||||
'directorySeparator' => DIRECTORY_SEPARATOR,
|
||||
];
|
||||
}
|
||||
|
||||
protected function mergeWithDefaultConfig(array $options = []): array
|
||||
{
|
||||
return array_merge(config('ignition') ?: include __DIR__.'/../config/ignition.php', $options);
|
||||
}
|
||||
}
|
||||
559
vendor/facade/ignition/src/IgnitionServiceProvider.php
vendored
Normal file
559
vendor/facade/ignition/src/IgnitionServiceProvider.php
vendored
Normal file
@@ -0,0 +1,559 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition;
|
||||
|
||||
use Exception;
|
||||
use Facade\FlareClient\Api;
|
||||
use Facade\FlareClient\Flare;
|
||||
use Facade\FlareClient\Http\Client;
|
||||
use Facade\Ignition\Commands\SolutionMakeCommand;
|
||||
use Facade\Ignition\Commands\SolutionProviderMakeCommand;
|
||||
use Facade\Ignition\Commands\TestCommand;
|
||||
use Facade\Ignition\Context\LaravelContextDetector;
|
||||
use Facade\Ignition\DumpRecorder\DumpRecorder;
|
||||
use Facade\Ignition\ErrorPage\IgnitionExceptionRenderer;
|
||||
use Facade\Ignition\ErrorPage\IgnitionWhoopsHandler;
|
||||
use Facade\Ignition\ErrorPage\Renderer;
|
||||
use Facade\Ignition\Exceptions\InvalidConfig;
|
||||
use Facade\Ignition\Http\Controllers\ExecuteSolutionController;
|
||||
use Facade\Ignition\Http\Controllers\HealthCheckController;
|
||||
use Facade\Ignition\Http\Controllers\ScriptController;
|
||||
use Facade\Ignition\Http\Controllers\ShareReportController;
|
||||
use Facade\Ignition\Http\Controllers\StyleController;
|
||||
use Facade\Ignition\Http\Middleware\IgnitionConfigValueEnabled;
|
||||
use Facade\Ignition\Http\Middleware\IgnitionEnabled;
|
||||
use Facade\Ignition\JobRecorder\JobRecorder;
|
||||
use Facade\Ignition\Logger\FlareHandler;
|
||||
use Facade\Ignition\LogRecorder\LogRecorder;
|
||||
use Facade\Ignition\Middleware\AddDumps;
|
||||
use Facade\Ignition\Middleware\AddEnvironmentInformation;
|
||||
use Facade\Ignition\Middleware\AddExceptionInformation;
|
||||
use Facade\Ignition\Middleware\AddGitInformation;
|
||||
use Facade\Ignition\Middleware\AddJobInformation;
|
||||
use Facade\Ignition\Middleware\AddLogs;
|
||||
use Facade\Ignition\Middleware\AddQueries;
|
||||
use Facade\Ignition\Middleware\AddSolutions;
|
||||
use Facade\Ignition\Middleware\SetNotifierName;
|
||||
use Facade\Ignition\QueryRecorder\QueryRecorder;
|
||||
use Facade\Ignition\SolutionProviders\BadMethodCallSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\DefaultDbNameSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\IncorrectValetDbCredentialsSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\InvalidRouteActionSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\LazyLoadingViolationSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MergeConflictSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MissingAppKeySolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MissingColumnSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MissingImportSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MissingLivewireComponentSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MissingMixManifestSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\MissingPackageSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\RunningLaravelDuskInProductionProvider;
|
||||
use Facade\Ignition\SolutionProviders\SolutionProviderRepository;
|
||||
use Facade\Ignition\SolutionProviders\TableNotFoundSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\UndefinedLivewireMethodSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\UndefinedLivewirePropertySolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\UndefinedPropertySolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\UndefinedVariableSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\UnknownValidationSolutionProvider;
|
||||
use Facade\Ignition\SolutionProviders\ViewNotFoundSolutionProvider;
|
||||
use Facade\Ignition\Support\SentReports;
|
||||
use Facade\Ignition\Views\Engines\CompilerEngine;
|
||||
use Facade\Ignition\Views\Engines\PhpEngine;
|
||||
use Facade\IgnitionContracts\SolutionProviderRepository as SolutionProviderRepositoryContract;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Log\Events\MessageLogged;
|
||||
use Illuminate\Log\LogManager;
|
||||
use Illuminate\Queue\QueueManager;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\View\Engines\CompilerEngine as LaravelCompilerEngine;
|
||||
use Illuminate\View\Engines\PhpEngine as LaravelPhpEngine;
|
||||
use Laravel\Octane\Events\RequestReceived;
|
||||
use Laravel\Octane\Events\TaskReceived;
|
||||
use Laravel\Octane\Events\TickReceived;
|
||||
use Livewire\CompilerEngineForIgnition;
|
||||
use Monolog\Logger;
|
||||
use Throwable;
|
||||
|
||||
class IgnitionServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->publishes([
|
||||
__DIR__.'/../config/flare.php' => config_path('flare.php'),
|
||||
], 'flare-config');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__.'/../config/ignition.php' => config_path('ignition.php'),
|
||||
], 'ignition-config');
|
||||
|
||||
if (isset($_SERVER['argv']) && ['artisan', 'tinker'] === $_SERVER['argv']) {
|
||||
Api::sendReportsInBatches(false);
|
||||
}
|
||||
|
||||
$this->app->make(JobRecorder::class)->register();
|
||||
}
|
||||
|
||||
$this
|
||||
->registerViewEngines()
|
||||
->registerHousekeepingRoutes()
|
||||
->registerLogHandler()
|
||||
->registerCommands();
|
||||
|
||||
if ($this->app->bound('queue')) {
|
||||
$this->setupQueue($this->app->get('queue'));
|
||||
}
|
||||
|
||||
if (isset($_SERVER['LARAVEL_OCTANE'])) {
|
||||
$this->setupOctane();
|
||||
}
|
||||
|
||||
if (config('flare.reporting.report_logs', true)) {
|
||||
$this->app->make(LogRecorder::class)->register();
|
||||
}
|
||||
|
||||
if (config('flare.reporting.report_queries', true)) {
|
||||
$this->app->make(QueryRecorder::class)->register();
|
||||
}
|
||||
|
||||
$this->app->make(DumpRecorder::class)->register();
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->mergeConfigFrom(__DIR__.'/../config/flare.php', 'flare');
|
||||
$this->mergeConfigFrom(__DIR__.'/../config/ignition.php', 'ignition');
|
||||
|
||||
$this
|
||||
->registerSolutionProviderRepository()
|
||||
->registerRenderer()
|
||||
->registerExceptionRenderer()
|
||||
->registerIgnitionConfig()
|
||||
->registerFlare()
|
||||
->registerDumpCollector()
|
||||
->registerJobRecorder();
|
||||
|
||||
if (config('flare.reporting.report_logs', true)) {
|
||||
$this->registerLogRecorder();
|
||||
}
|
||||
|
||||
if (config('flare.reporting.report_queries', true)) {
|
||||
$this->registerQueryRecorder();
|
||||
}
|
||||
|
||||
if (config('flare.reporting.anonymize_ips')) {
|
||||
$this->app->get(Flare::class)->anonymizeIp();
|
||||
}
|
||||
|
||||
$this->app->get(Flare::class)->censorRequestBodyFields(config('flare.reporting.censor_request_body_fields', ['password']));
|
||||
|
||||
$this->registerBuiltInMiddleware();
|
||||
}
|
||||
|
||||
protected function registerViewEngines()
|
||||
{
|
||||
if (! $this->hasCustomViewEnginesRegistered()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->app->make('view.engine.resolver')->register('php', function () {
|
||||
return new PhpEngine($this->app['files']);
|
||||
});
|
||||
|
||||
$this->app->make('view.engine.resolver')->register('blade', function () {
|
||||
if (class_exists(CompilerEngineForIgnition::class)) {
|
||||
return new CompilerEngineForIgnition($this->app['blade.compiler']);
|
||||
}
|
||||
|
||||
return new CompilerEngine($this->app['blade.compiler']);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerHousekeepingRoutes()
|
||||
{
|
||||
if ($this->app->runningInConsole()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
Route::group([
|
||||
'as' => 'ignition.',
|
||||
'prefix' => config('ignition.housekeeping_endpoint_prefix', '_ignition'),
|
||||
'middleware' => [IgnitionEnabled::class],
|
||||
], function () {
|
||||
Route::get('health-check', HealthCheckController::class)->name('healthCheck');
|
||||
|
||||
Route::post('execute-solution', ExecuteSolutionController::class)
|
||||
->middleware(IgnitionConfigValueEnabled::class.':enableRunnableSolutions')
|
||||
->name('executeSolution');
|
||||
|
||||
Route::post('share-report', ShareReportController::class)
|
||||
->middleware(IgnitionConfigValueEnabled::class.':enableShareButton')
|
||||
->name('shareReport');
|
||||
|
||||
Route::get('scripts/{script}', ScriptController::class)->name('scripts');
|
||||
Route::get('styles/{style}', StyleController::class)->name('styles');
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerSolutionProviderRepository()
|
||||
{
|
||||
$this->app->singleton(SolutionProviderRepositoryContract::class, function () {
|
||||
$defaultSolutions = $this->getDefaultSolutions();
|
||||
|
||||
return new SolutionProviderRepository($defaultSolutions);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerRenderer()
|
||||
{
|
||||
$this->app->bind(Renderer::class, function () {
|
||||
return new Renderer(__DIR__.'/../resources/views/');
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerExceptionRenderer()
|
||||
{
|
||||
if (interface_exists(\Whoops\Handler\HandlerInterface::class)) {
|
||||
$this->app->bind(\Whoops\Handler\HandlerInterface::class, function (Application $app) {
|
||||
return $app->make(IgnitionWhoopsHandler::class);
|
||||
});
|
||||
}
|
||||
|
||||
if (interface_exists(\Illuminate\Contracts\Foundation\ExceptionRenderer::class)) {
|
||||
$this->app->bind(\Illuminate\Contracts\Foundation\ExceptionRenderer::class, function (Application $app) {
|
||||
return $app->make(IgnitionExceptionRenderer::class);
|
||||
});
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerIgnitionConfig()
|
||||
{
|
||||
$this->app->singleton(IgnitionConfig::class, function () {
|
||||
$options = [];
|
||||
|
||||
try {
|
||||
if ($configPath = $this->getConfigFileLocation()) {
|
||||
$options = require $configPath;
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
// possible open_basedir restriction
|
||||
}
|
||||
|
||||
return new IgnitionConfig($options);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerFlare()
|
||||
{
|
||||
$this->app->singleton('flare.http', function () {
|
||||
return new Client(
|
||||
config('flare.key'),
|
||||
config('flare.secret'),
|
||||
config('flare.base_url', 'https://reporting.flareapp.io/api')
|
||||
);
|
||||
});
|
||||
|
||||
$this->app->singleton(SentReports::class);
|
||||
|
||||
$this->app->alias('flare.http', Client::class);
|
||||
|
||||
$this->app->singleton(Flare::class, function () {
|
||||
$client = new Flare($this->app->get('flare.http'), new LaravelContextDetector(), $this->app);
|
||||
$client->applicationPath(base_path());
|
||||
$client->stage(config('app.env'));
|
||||
|
||||
return $client;
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerLogHandler()
|
||||
{
|
||||
$this->app->singleton('flare.logger', function ($app) {
|
||||
$handler = new FlareHandler(
|
||||
$app->make(Flare::class),
|
||||
$app->make(SentReports::class)
|
||||
);
|
||||
|
||||
$logLevelString = config('logging.channels.flare.level', 'error');
|
||||
|
||||
$logLevel = $this->getLogLevel($logLevelString);
|
||||
|
||||
$handler->setMinimumReportLogLevel($logLevel);
|
||||
|
||||
$logger = new Logger('Flare');
|
||||
$logger->pushHandler($handler);
|
||||
|
||||
return $logger;
|
||||
});
|
||||
|
||||
if ($this->app['log'] instanceof LogManager) {
|
||||
Log::extend('flare', function ($app) {
|
||||
return $app['flare.logger'];
|
||||
});
|
||||
} else {
|
||||
$this->bindLogListener();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getLogLevel(string $logLevelString): int
|
||||
{
|
||||
$logLevel = Logger::getLevels()[strtoupper($logLevelString)] ?? null;
|
||||
|
||||
if (! $logLevel) {
|
||||
throw InvalidConfig::invalidLogLevel($logLevelString);
|
||||
}
|
||||
|
||||
return $logLevel;
|
||||
}
|
||||
|
||||
protected function registerLogRecorder(): self
|
||||
{
|
||||
$this->app->singleton(LogRecorder::class, function (Application $app): LogRecorder {
|
||||
return new LogRecorder(
|
||||
$app,
|
||||
$app->get('config')->get('flare.reporting.maximum_number_of_collected_logs')
|
||||
);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerDumpCollector()
|
||||
{
|
||||
$dumpCollector = $this->app->make(DumpRecorder::class);
|
||||
|
||||
$this->app->singleton(DumpRecorder::class);
|
||||
|
||||
$this->app->instance(DumpRecorder::class, $dumpCollector);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerJobRecorder()
|
||||
{
|
||||
if (! $this->app->runningInConsole()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->app->singleton(JobRecorder::class);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerCommands()
|
||||
{
|
||||
$this->app->bind('command.flare:test', TestCommand::class);
|
||||
$this->app->bind('command.make:solution', SolutionMakeCommand::class);
|
||||
$this->app->bind('command.make:solution-provider', SolutionProviderMakeCommand::class);
|
||||
|
||||
if ($this->app['config']->get('flare.key')) {
|
||||
$this->commands(['command.flare:test']);
|
||||
}
|
||||
|
||||
if ($this->app['config']->get('ignition.register_commands', false)) {
|
||||
$this->commands(['command.make:solution']);
|
||||
$this->commands(['command.make:solution-provider']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerQueryRecorder(): self
|
||||
{
|
||||
$this->app->singleton(QueryRecorder::class, function (Application $app): QueryRecorder {
|
||||
return new QueryRecorder(
|
||||
$app,
|
||||
$app->get('config')->get('flare.reporting.report_query_bindings'),
|
||||
$app->get('config')->get('flare.reporting.maximum_number_of_collected_queries')
|
||||
);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function registerBuiltInMiddleware()
|
||||
{
|
||||
$middlewares = [
|
||||
SetNotifierName::class,
|
||||
AddEnvironmentInformation::class,
|
||||
AddExceptionInformation::class,
|
||||
];
|
||||
|
||||
if (config('flare.reporting.report_logs', true)) {
|
||||
$middlewares[] = AddLogs::class;
|
||||
}
|
||||
|
||||
$middlewares[] = AddDumps::class;
|
||||
|
||||
if (config('flare.reporting.report_queries', true)) {
|
||||
$middlewares[] = AddQueries::class;
|
||||
}
|
||||
|
||||
$middlewares[] = AddSolutions::class;
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$middlewares[] = AddJobInformation::class;
|
||||
}
|
||||
|
||||
$middleware = collect($middlewares)
|
||||
->map(function (string $middlewareClass) {
|
||||
return $this->app->make($middlewareClass);
|
||||
});
|
||||
|
||||
if (config('flare.reporting.collect_git_information')) {
|
||||
$middleware[] = (new AddGitInformation());
|
||||
}
|
||||
|
||||
foreach ($middleware as $singleMiddleware) {
|
||||
$this->app->get(Flare::class)->registerMiddleware($singleMiddleware);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getDefaultSolutions(): array
|
||||
{
|
||||
return [
|
||||
IncorrectValetDbCredentialsSolutionProvider::class,
|
||||
MissingAppKeySolutionProvider::class,
|
||||
DefaultDbNameSolutionProvider::class,
|
||||
BadMethodCallSolutionProvider::class,
|
||||
TableNotFoundSolutionProvider::class,
|
||||
MissingImportSolutionProvider::class,
|
||||
MissingPackageSolutionProvider::class,
|
||||
InvalidRouteActionSolutionProvider::class,
|
||||
ViewNotFoundSolutionProvider::class,
|
||||
UndefinedVariableSolutionProvider::class,
|
||||
MergeConflictSolutionProvider::class,
|
||||
RunningLaravelDuskInProductionProvider::class,
|
||||
MissingColumnSolutionProvider::class,
|
||||
UnknownValidationSolutionProvider::class,
|
||||
UndefinedLivewireMethodSolutionProvider::class,
|
||||
UndefinedLivewirePropertySolutionProvider::class,
|
||||
UndefinedPropertySolutionProvider::class,
|
||||
MissingMixManifestSolutionProvider::class,
|
||||
MissingLivewireComponentSolutionProvider::class,
|
||||
LazyLoadingViolationSolutionProvider::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function hasCustomViewEnginesRegistered()
|
||||
{
|
||||
$resolver = $this->app->make('view.engine.resolver');
|
||||
|
||||
if (! $resolver->resolve('php') instanceof LaravelPhpEngine) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $resolver->resolve('blade') instanceof LaravelCompilerEngine) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function bindLogListener()
|
||||
{
|
||||
$this->app['log']->listen(function (MessageLogged $messageLogged) {
|
||||
if (config('flare.key')) {
|
||||
try {
|
||||
$this->app['flare.logger']->log(
|
||||
$messageLogged->level,
|
||||
$messageLogged->message,
|
||||
$messageLogged->context
|
||||
);
|
||||
} catch (Exception $exception) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function getConfigFileLocation(): ?string
|
||||
{
|
||||
$configFullPath = base_path().DIRECTORY_SEPARATOR.'.ignition';
|
||||
|
||||
if (file_exists($configFullPath)) {
|
||||
return $configFullPath;
|
||||
}
|
||||
|
||||
$configFullPath = Arr::get($_SERVER, 'HOME', '').DIRECTORY_SEPARATOR.'.ignition';
|
||||
|
||||
if (file_exists($configFullPath)) {
|
||||
return $configFullPath;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function resetFlare()
|
||||
{
|
||||
$this->app->get(SentReports::class)->clear();
|
||||
$this->app->get(Flare::class)->reset();
|
||||
|
||||
if (config('flare.reporting.report_logs', true)) {
|
||||
$this->app->make(LogRecorder::class)->reset();
|
||||
}
|
||||
|
||||
if (config('flare.reporting.report_queries', true)) {
|
||||
$this->app->make(QueryRecorder::class)->reset();
|
||||
}
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->app->make(JobRecorder::class)->reset();
|
||||
}
|
||||
|
||||
$this->app->make(DumpRecorder::class)->reset();
|
||||
}
|
||||
|
||||
protected function setupQueue(QueueManager $queue)
|
||||
{
|
||||
// Reset before executing a queue job to make sure the job's log/query/dump recorders are empty.
|
||||
// When using a sync queue this also reports the queued reports from previous exceptions.
|
||||
$queue->before(function () {
|
||||
$this->resetFlare();
|
||||
});
|
||||
|
||||
// Send queued reports (and reset) after executing a queue job.
|
||||
$queue->after(function () {
|
||||
$this->resetFlare();
|
||||
});
|
||||
|
||||
// Note: the $queue->looping() event can't be used because it's not triggered on Vapor
|
||||
}
|
||||
|
||||
/** @psalm-suppress UndefinedClass */
|
||||
protected function setupOctane()
|
||||
{
|
||||
$this->app['events']->listen(RequestReceived::class, function () {
|
||||
$this->resetFlare();
|
||||
});
|
||||
|
||||
$this->app['events']->listen(TaskReceived::class, function () {
|
||||
$this->resetFlare();
|
||||
});
|
||||
|
||||
$this->app['events']->listen(TickReceived::class, function () {
|
||||
$this->resetFlare();
|
||||
});
|
||||
}
|
||||
}
|
||||
167
vendor/facade/ignition/src/JobRecorder/JobRecorder.php
vendored
Normal file
167
vendor/facade/ignition/src/JobRecorder/JobRecorder.php
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\JobRecorder;
|
||||
|
||||
use DateTime;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Encryption\Encrypter;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\Queue\Job;
|
||||
use Illuminate\Queue\CallQueuedClosure;
|
||||
use Illuminate\Queue\Events\JobExceptionOccurred;
|
||||
use Illuminate\Queue\Jobs\RedisJob;
|
||||
use Illuminate\Support\Str;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use RuntimeException;
|
||||
|
||||
class JobRecorder
|
||||
{
|
||||
/** @var \Illuminate\Contracts\Foundation\Application */
|
||||
protected $app;
|
||||
|
||||
/** @var \Illuminate\Contracts\Queue\Job|null */
|
||||
protected $job = null;
|
||||
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
public function register(): self
|
||||
{
|
||||
$this->app['events']->listen(JobExceptionOccurred::class, [$this, 'record']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function record(JobExceptionOccurred $event): void
|
||||
{
|
||||
$this->job = $event->job;
|
||||
}
|
||||
|
||||
public function getJob(): ?Job
|
||||
{
|
||||
return $this->job;
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->job = null;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
if ($this->job === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
$this->getJobProperties(),
|
||||
[
|
||||
'name' => $this->job->resolveName(),
|
||||
'connection' => $this->job->getConnectionName(),
|
||||
'queue' => $this->job->getQueue(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getJobProperties(): array
|
||||
{
|
||||
$payload = collect($this->resolveJobPayload());
|
||||
|
||||
$properties = [];
|
||||
|
||||
foreach ($payload as $key => $value) {
|
||||
if (! in_array($key, ['job', 'data', 'displayName'])) {
|
||||
$properties[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($pushedAt = DateTime::createFromFormat('U.u', $payload->get('pushedAt', ''))) {
|
||||
$properties['pushedAt'] = $pushedAt->format(DATE_ATOM);
|
||||
}
|
||||
|
||||
try {
|
||||
$properties['data'] = $this->resolveCommandProperties(
|
||||
$this->resolveObjectFromCommand($payload['data']['command']),
|
||||
config('ignition.max_chained_job_reporting_depth', 5)
|
||||
);
|
||||
} catch (Exception $exception) {
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
protected function resolveJobPayload(): array
|
||||
{
|
||||
if (! $this->job instanceof RedisJob) {
|
||||
return $this->job->payload();
|
||||
}
|
||||
|
||||
try {
|
||||
return json_decode($this->job->getReservedJob(), true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (Exception $e) {
|
||||
return $this->job->payload();
|
||||
}
|
||||
}
|
||||
|
||||
protected function resolveCommandProperties(object $command, int $maxChainDepth): array
|
||||
{
|
||||
$propertiesToIgnore = ['job', 'closure'];
|
||||
|
||||
$properties = collect((new ReflectionClass($command))->getProperties())
|
||||
->reject(function (ReflectionProperty $property) use ($propertiesToIgnore) {
|
||||
return in_array($property->name, $propertiesToIgnore);
|
||||
})
|
||||
->mapWithKeys(function (ReflectionProperty $property) use ($command) {
|
||||
try {
|
||||
$property->setAccessible(true);
|
||||
|
||||
return [$property->name => $property->getValue($command)];
|
||||
} catch (Error $error) {
|
||||
return [$property->name => 'uninitialized'];
|
||||
}
|
||||
});
|
||||
|
||||
if ($properties->has('chained')) {
|
||||
$properties['chained'] = $this->resolveJobChain($properties->get('chained'), $maxChainDepth);
|
||||
}
|
||||
|
||||
return $properties->all();
|
||||
}
|
||||
|
||||
protected function resolveJobChain(array $chainedCommands, int $maxDepth): array
|
||||
{
|
||||
if ($maxDepth === 0) {
|
||||
return ['Ignition stopped recording jobs after this point since the max chain depth was reached'];
|
||||
}
|
||||
|
||||
return array_map(
|
||||
function (string $command) use ($maxDepth) {
|
||||
$commandObject = $this->resolveObjectFromCommand($command);
|
||||
|
||||
return [
|
||||
'name' => $commandObject instanceof CallQueuedClosure ? $commandObject->displayName() : get_class($commandObject),
|
||||
'data' => $this->resolveCommandProperties($commandObject, $maxDepth - 1),
|
||||
];
|
||||
},
|
||||
$chainedCommands
|
||||
);
|
||||
}
|
||||
|
||||
// Taken from Illuminate\Queue\CallQueuedHandler
|
||||
protected function resolveObjectFromCommand(string $command): object
|
||||
{
|
||||
if (Str::startsWith($command, 'O:')) {
|
||||
return unserialize($command);
|
||||
}
|
||||
|
||||
if ($this->app->bound(Encrypter::class)) {
|
||||
return unserialize($this->app[Encrypter::class]->decrypt($command));
|
||||
}
|
||||
|
||||
throw new RuntimeException('Unable to extract job payload.');
|
||||
}
|
||||
}
|
||||
47
vendor/facade/ignition/src/LogRecorder/LogMessage.php
vendored
Normal file
47
vendor/facade/ignition/src/LogRecorder/LogMessage.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\LogRecorder;
|
||||
|
||||
use Illuminate\Log\Events\MessageLogged;
|
||||
|
||||
class LogMessage
|
||||
{
|
||||
/** @var string */
|
||||
protected $message;
|
||||
|
||||
/** @var array */
|
||||
protected $context;
|
||||
|
||||
/** @var string */
|
||||
protected $level;
|
||||
|
||||
/** @var float */
|
||||
protected $microtime;
|
||||
|
||||
public function __construct(?string $message, string $level, array $context = [], ?float $microtime = null)
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->level = $level;
|
||||
$this->context = $context;
|
||||
$this->microtime = $microtime ?? microtime(true);
|
||||
}
|
||||
|
||||
public static function fromMessageLoggedEvent(MessageLogged $event): self
|
||||
{
|
||||
return new self(
|
||||
$event->message,
|
||||
$event->level,
|
||||
$event->context
|
||||
);
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'message' => $this->message,
|
||||
'level' => $this->level,
|
||||
'context' => $this->context,
|
||||
'microtime' => $this->microtime,
|
||||
];
|
||||
}
|
||||
}
|
||||
91
vendor/facade/ignition/src/LogRecorder/LogRecorder.php
vendored
Normal file
91
vendor/facade/ignition/src/LogRecorder/LogRecorder.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\LogRecorder;
|
||||
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Log\Events\MessageLogged;
|
||||
use Throwable;
|
||||
|
||||
class LogRecorder
|
||||
{
|
||||
/** @var \Facade\Ignition\LogRecorder\LogMessage[] */
|
||||
protected $logMessages = [];
|
||||
|
||||
/** @var \Illuminate\Contracts\Foundation\Application */
|
||||
protected $app;
|
||||
|
||||
/** @var int|null */
|
||||
private $maxLogs;
|
||||
|
||||
public function __construct(Application $app, ?int $maxLogs = null)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->maxLogs = $maxLogs;
|
||||
}
|
||||
|
||||
public function register(): self
|
||||
{
|
||||
$this->app['events']->listen(MessageLogged::class, [$this, 'record']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function record(MessageLogged $event): void
|
||||
{
|
||||
if ($this->shouldIgnore($event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logMessages[] = LogMessage::fromMessageLoggedEvent($event);
|
||||
|
||||
if (is_int($this->maxLogs)) {
|
||||
$this->logMessages = array_slice($this->logMessages, -$this->maxLogs);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLogMessages(): array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$logMessages = [];
|
||||
|
||||
foreach ($this->logMessages as $log) {
|
||||
$logMessages[] = $log->toArray();
|
||||
}
|
||||
|
||||
return $logMessages;
|
||||
}
|
||||
|
||||
protected function shouldIgnore($event): bool
|
||||
{
|
||||
if (! isset($event->context['exception'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $event->context['exception'] instanceof Throwable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->logMessages = [];
|
||||
}
|
||||
|
||||
public function getMaxLogs(): ?int
|
||||
{
|
||||
return $this->maxLogs;
|
||||
}
|
||||
|
||||
public function setMaxLogs(?int $maxLogs): self
|
||||
{
|
||||
$this->maxLogs = $maxLogs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
101
vendor/facade/ignition/src/Logger/FlareHandler.php
vendored
Normal file
101
vendor/facade/ignition/src/Logger/FlareHandler.php
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Logger;
|
||||
|
||||
use Facade\FlareClient\Flare;
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\Ignition;
|
||||
use Facade\Ignition\Support\SentReports;
|
||||
use Facade\Ignition\Tabs\Tab;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Logger;
|
||||
use Throwable;
|
||||
|
||||
class FlareHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/** @var \Facade\FlareClient\Flare */
|
||||
protected $flare;
|
||||
|
||||
/** @var \Facade\Ignition\Support\SentReports */
|
||||
protected $sentReports;
|
||||
|
||||
protected $minimumReportLogLevel = Logger::ERROR;
|
||||
|
||||
public function __construct(Flare $flare, SentReports $sentReports, $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
$this->flare = $flare;
|
||||
|
||||
$this->sentReports = $sentReports;
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
||||
public function setMinimumReportLogLevel(int $level)
|
||||
{
|
||||
if (! in_array($level, Logger::getLevels())) {
|
||||
throw new \InvalidArgumentException('The given minimum log level is not supported.');
|
||||
}
|
||||
|
||||
$this->minimumReportLogLevel = $level;
|
||||
}
|
||||
|
||||
protected function write(array $record): void
|
||||
{
|
||||
if (! $this->shouldReport($record)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->hasException($record)) {
|
||||
/** @var Throwable $throwable */
|
||||
$throwable = $record['context']['exception'];
|
||||
|
||||
collect(Ignition::$tabs)
|
||||
->each(function (Tab $tab) use ($throwable) {
|
||||
$tab->beforeRenderingErrorPage($this->flare, $throwable);
|
||||
});
|
||||
|
||||
$report = $this->flare->report($record['context']['exception']);
|
||||
|
||||
if ($report) {
|
||||
$this->sentReports->add($report);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (config('flare.send_logs_as_events')) {
|
||||
if ($this->hasValidLogLevel($record)) {
|
||||
$this->flare->reportMessage(
|
||||
$record['message'],
|
||||
'Log ' . Logger::getLevelName($record['level']),
|
||||
function (Report $flareReport) use ($record) {
|
||||
foreach ($record['context'] as $key => $value) {
|
||||
$flareReport->context($key, $value);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function shouldReport(array $report): bool
|
||||
{
|
||||
if (! config('flare.key')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->hasException($report) || $this->hasValidLogLevel($report);
|
||||
}
|
||||
|
||||
protected function hasException(array $report): bool
|
||||
{
|
||||
$context = $report['context'];
|
||||
|
||||
return isset($context['exception']) && $context['exception'] instanceof Throwable;
|
||||
}
|
||||
|
||||
protected function hasValidLogLevel(array $report): bool
|
||||
{
|
||||
return $report['level'] >= $this->minimumReportLogLevel;
|
||||
}
|
||||
}
|
||||
24
vendor/facade/ignition/src/Middleware/AddDumps.php
vendored
Normal file
24
vendor/facade/ignition/src/Middleware/AddDumps.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\DumpRecorder\DumpRecorder;
|
||||
|
||||
class AddDumps
|
||||
{
|
||||
/** @var \Facade\Ignition\DumpRecorder\DumpRecorder */
|
||||
protected $dumpRecorder;
|
||||
|
||||
public function __construct(DumpRecorder $dumpRecorder)
|
||||
{
|
||||
$this->dumpRecorder = $dumpRecorder;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$report->group('dumps', $this->dumpRecorder->getDumps());
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
22
vendor/facade/ignition/src/Middleware/AddEnvironmentInformation.php
vendored
Normal file
22
vendor/facade/ignition/src/Middleware/AddEnvironmentInformation.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
|
||||
class AddEnvironmentInformation
|
||||
{
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$report->frameworkVersion(app()->version());
|
||||
|
||||
$report->group('env', [
|
||||
'laravel_version' => app()->version(),
|
||||
'laravel_locale' => app()->getLocale(),
|
||||
'laravel_config_cached' => app()->configurationIsCached(),
|
||||
'php_version' => phpversion(),
|
||||
]);
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
24
vendor/facade/ignition/src/Middleware/AddExceptionInformation.php
vendored
Normal file
24
vendor/facade/ignition/src/Middleware/AddExceptionInformation.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
||||
class AddExceptionInformation
|
||||
{
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$throwable = $report->getThrowable();
|
||||
|
||||
if (! $throwable instanceof QueryException) {
|
||||
return $next($report);
|
||||
}
|
||||
|
||||
$report->group('exception', [
|
||||
'raw_sql' => $throwable->getSql(),
|
||||
]);
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
57
vendor/facade/ignition/src/Middleware/AddGitInformation.php
vendored
Normal file
57
vendor/facade/ignition/src/Middleware/AddGitInformation.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use ReflectionClass;
|
||||
use Symfony\Component\Process\Exception\RuntimeException;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
class AddGitInformation
|
||||
{
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
try {
|
||||
$report->group('git', [
|
||||
'hash' => $this->hash(),
|
||||
'message' => $this->message(),
|
||||
'tag' => $this->tag(),
|
||||
'remote' => $this->remote(),
|
||||
]);
|
||||
} catch (RuntimeException $exception) {
|
||||
}
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
|
||||
public function hash(): ?string
|
||||
{
|
||||
return $this->command("git log --pretty=format:'%H' -n 1");
|
||||
}
|
||||
|
||||
public function message(): ?string
|
||||
{
|
||||
return $this->command("git log --pretty=format:'%s' -n 1");
|
||||
}
|
||||
|
||||
public function tag(): ?string
|
||||
{
|
||||
return $this->command('git describe --tags --abbrev=0');
|
||||
}
|
||||
|
||||
public function remote(): ?string
|
||||
{
|
||||
return $this->command('git config --get remote.origin.url');
|
||||
}
|
||||
|
||||
protected function command($command)
|
||||
{
|
||||
$process = (new ReflectionClass(Process::class))->hasMethod('fromShellCommandline')
|
||||
? Process::fromShellCommandline($command, base_path())
|
||||
: new Process($command, base_path());
|
||||
|
||||
$process->run();
|
||||
|
||||
return trim($process->getOutput());
|
||||
}
|
||||
}
|
||||
26
vendor/facade/ignition/src/Middleware/AddJobInformation.php
vendored
Normal file
26
vendor/facade/ignition/src/Middleware/AddJobInformation.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\JobRecorder\JobRecorder;
|
||||
|
||||
class AddJobInformation
|
||||
{
|
||||
/** @var \Facade\Ignition\JobRecorder\JobRecorder */
|
||||
protected $jobRecorder;
|
||||
|
||||
public function __construct(JobRecorder $jobRecorder)
|
||||
{
|
||||
$this->jobRecorder = $jobRecorder;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
if ($this->jobRecorder->getJob()) {
|
||||
$report->group('job', $this->jobRecorder->toArray());
|
||||
}
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
24
vendor/facade/ignition/src/Middleware/AddLogs.php
vendored
Normal file
24
vendor/facade/ignition/src/Middleware/AddLogs.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\LogRecorder\LogRecorder;
|
||||
|
||||
class AddLogs
|
||||
{
|
||||
/** @var \Facade\Ignition\LogRecorder\LogRecorder */
|
||||
protected $logRecorder;
|
||||
|
||||
public function __construct(LogRecorder $logRecorder)
|
||||
{
|
||||
$this->logRecorder = $logRecorder;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$report->group('logs', $this->logRecorder->getLogMessages());
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
24
vendor/facade/ignition/src/Middleware/AddQueries.php
vendored
Normal file
24
vendor/facade/ignition/src/Middleware/AddQueries.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\Ignition\QueryRecorder\QueryRecorder;
|
||||
|
||||
class AddQueries
|
||||
{
|
||||
/** @var \Facade\Ignition\QueryRecorder\QueryRecorder */
|
||||
protected $queryRecorder;
|
||||
|
||||
public function __construct(QueryRecorder $queryRecorder)
|
||||
{
|
||||
$this->queryRecorder = $queryRecorder;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$report->group('queries', $this->queryRecorder->getQueries());
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
30
vendor/facade/ignition/src/Middleware/AddSolutions.php
vendored
Normal file
30
vendor/facade/ignition/src/Middleware/AddSolutions.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
use Facade\IgnitionContracts\SolutionProviderRepository;
|
||||
|
||||
class AddSolutions
|
||||
{
|
||||
/** @var \Facade\IgnitionContracts\SolutionProviderRepository */
|
||||
protected $solutionProviderRepository;
|
||||
|
||||
public function __construct(SolutionProviderRepository $solutionProviderRepository)
|
||||
{
|
||||
$this->solutionProviderRepository = $solutionProviderRepository;
|
||||
}
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
if ($throwable = $report->getThrowable()) {
|
||||
$solutions = $this->solutionProviderRepository->getSolutionsForThrowable($throwable);
|
||||
|
||||
foreach ($solutions as $solution) {
|
||||
$report->addSolution($solution);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
17
vendor/facade/ignition/src/Middleware/SetNotifierName.php
vendored
Normal file
17
vendor/facade/ignition/src/Middleware/SetNotifierName.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Middleware;
|
||||
|
||||
use Facade\FlareClient\Report;
|
||||
|
||||
class SetNotifierName
|
||||
{
|
||||
public const NOTIFIER_NAME = 'Laravel Client';
|
||||
|
||||
public function handle(Report $report, $next)
|
||||
{
|
||||
$report->notifierName(static::NOTIFIER_NAME);
|
||||
|
||||
return $next($report);
|
||||
}
|
||||
}
|
||||
58
vendor/facade/ignition/src/QueryRecorder/Query.php
vendored
Normal file
58
vendor/facade/ignition/src/QueryRecorder/Query.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\QueryRecorder;
|
||||
|
||||
use Illuminate\Database\Events\QueryExecuted;
|
||||
|
||||
class Query
|
||||
{
|
||||
/** @var string */
|
||||
protected $sql;
|
||||
|
||||
/** @var float */
|
||||
protected $time;
|
||||
|
||||
/** @var string */
|
||||
protected $connectionName;
|
||||
|
||||
/** @var null|array */
|
||||
protected $bindings;
|
||||
|
||||
/** @var float */
|
||||
protected $microtime;
|
||||
|
||||
public static function fromQueryExecutedEvent(QueryExecuted $queryExecuted, bool $reportBindings = false)
|
||||
{
|
||||
return new static(
|
||||
$queryExecuted->sql,
|
||||
$queryExecuted->time,
|
||||
$queryExecuted->connectionName ?? '',
|
||||
$reportBindings ? $queryExecuted->bindings : null
|
||||
);
|
||||
}
|
||||
|
||||
protected function __construct(
|
||||
string $sql,
|
||||
float $time,
|
||||
string $connectionName,
|
||||
?array $bindings = null,
|
||||
?float $microtime = null
|
||||
) {
|
||||
$this->sql = $sql;
|
||||
$this->time = $time;
|
||||
$this->connectionName = $connectionName;
|
||||
$this->bindings = $bindings;
|
||||
$this->microtime = $microtime ?? microtime(true);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'sql' => $this->sql,
|
||||
'time' => $this->time,
|
||||
'connection_name' => $this->connectionName,
|
||||
'bindings' => $this->bindings,
|
||||
'microtime' => $this->microtime,
|
||||
];
|
||||
}
|
||||
}
|
||||
87
vendor/facade/ignition/src/QueryRecorder/QueryRecorder.php
vendored
Normal file
87
vendor/facade/ignition/src/QueryRecorder/QueryRecorder.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\QueryRecorder;
|
||||
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Database\Events\QueryExecuted;
|
||||
|
||||
class QueryRecorder
|
||||
{
|
||||
/** @var \Facade\Ignition\QueryRecorder\Query|[] */
|
||||
protected $queries = [];
|
||||
|
||||
/** @var \Illuminate\Contracts\Foundation\Application */
|
||||
protected $app;
|
||||
|
||||
/** @var bool */
|
||||
private $reportBindings;
|
||||
|
||||
/** @var int|null */
|
||||
private $maxQueries;
|
||||
|
||||
public function __construct(
|
||||
Application $app,
|
||||
bool $reportBindings = true,
|
||||
?int $maxQueries = null
|
||||
) {
|
||||
$this->app = $app;
|
||||
$this->reportBindings = $reportBindings;
|
||||
$this->maxQueries = $maxQueries;
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app['events']->listen(QueryExecuted::class, [$this, 'record']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function record(QueryExecuted $queryExecuted)
|
||||
{
|
||||
$this->queries[] = Query::fromQueryExecutedEvent($queryExecuted, $this->reportBindings);
|
||||
|
||||
if (is_int($this->maxQueries)) {
|
||||
$this->queries = array_slice($this->queries, -$this->maxQueries);
|
||||
}
|
||||
}
|
||||
|
||||
public function getQueries(): array
|
||||
{
|
||||
$queries = [];
|
||||
|
||||
foreach ($this->queries as $query) {
|
||||
$queries[] = $query->toArray();
|
||||
}
|
||||
|
||||
return $queries;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->queries = [];
|
||||
}
|
||||
|
||||
public function getReportBindings(): bool
|
||||
{
|
||||
return $this->reportBindings;
|
||||
}
|
||||
|
||||
public function setReportBindings(bool $reportBindings): self
|
||||
{
|
||||
$this->reportBindings = $reportBindings;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMaxQueries(): ?int
|
||||
{
|
||||
return $this->maxQueries;
|
||||
}
|
||||
|
||||
public function setMaxQueries(?int $maxQueries): self
|
||||
{
|
||||
$this->maxQueries = $maxQueries;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
79
vendor/facade/ignition/src/SolutionProviders/BadMethodCallSolutionProvider.php
vendored
Normal file
79
vendor/facade/ignition/src/SolutionProviders/BadMethodCallSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Collection;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use Throwable;
|
||||
|
||||
class BadMethodCallSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
protected const REGEX = '/([a-zA-Z\\\\]+)::([a-zA-Z]+)/m';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof BadMethodCallException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_null($this->getClassAndMethodFromExceptionMessage($throwable->getMessage()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [
|
||||
BaseSolution::create('Bad Method Call')
|
||||
->setSolutionDescription($this->getSolutionDescription($throwable)),
|
||||
];
|
||||
}
|
||||
|
||||
public function getSolutionDescription(Throwable $throwable): string
|
||||
{
|
||||
if (! $this->canSolve($throwable)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
extract($this->getClassAndMethodFromExceptionMessage($throwable->getMessage()), EXTR_OVERWRITE);
|
||||
|
||||
$possibleMethod = $this->findPossibleMethod($class, $method);
|
||||
|
||||
return "Did you mean {$class}::{$possibleMethod->name}() ?";
|
||||
}
|
||||
|
||||
protected function getClassAndMethodFromExceptionMessage(string $message): ?array
|
||||
{
|
||||
if (! preg_match(self::REGEX, $message, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'class' => $matches[1],
|
||||
'method' => $matches[2],
|
||||
];
|
||||
}
|
||||
|
||||
protected function findPossibleMethod(string $class, string $invalidMethodName)
|
||||
{
|
||||
return $this->getAvailableMethods($class)
|
||||
->sortByDesc(function (ReflectionMethod $method) use ($invalidMethodName) {
|
||||
similar_text($invalidMethodName, $method->name, $percentage);
|
||||
|
||||
return $percentage;
|
||||
})->first();
|
||||
}
|
||||
|
||||
protected function getAvailableMethods($class): Collection
|
||||
{
|
||||
$class = new ReflectionClass($class);
|
||||
|
||||
return Collection::make($class->getMethods());
|
||||
}
|
||||
}
|
||||
35
vendor/facade/ignition/src/SolutionProviders/DefaultDbNameSolutionProvider.php
vendored
Normal file
35
vendor/facade/ignition/src/SolutionProviders/DefaultDbNameSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\SuggestUsingCorrectDbNameSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Throwable;
|
||||
|
||||
class DefaultDbNameSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public const MYSQL_UNKNOWN_DATABASE_CODE = 1049;
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof QueryException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($throwable->getCode() !== self::MYSQL_UNKNOWN_DATABASE_CODE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! in_array(env('DB_DATABASE'), ['homestead', 'laravel'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new SuggestUsingCorrectDbNameSolution()];
|
||||
}
|
||||
}
|
||||
67
vendor/facade/ignition/src/SolutionProviders/IncorrectValetDbCredentialsSolutionProvider.php
vendored
Normal file
67
vendor/facade/ignition/src/SolutionProviders/IncorrectValetDbCredentialsSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\UseDefaultValetDbCredentialsSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Throwable;
|
||||
|
||||
class IncorrectValetDbCredentialsSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public const MYSQL_ACCESS_DENIED_CODE = 1045;
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (PHP_OS !== 'Darwin') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $throwable instanceof QueryException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->isAccessDeniedCode($throwable->getCode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->envFileExists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->isValetInstalled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->usingCorrectDefaultCredentials()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new UseDefaultValetDbCredentialsSolution()];
|
||||
}
|
||||
|
||||
protected function envFileExists(): bool
|
||||
{
|
||||
return file_exists(base_path('.env'));
|
||||
}
|
||||
|
||||
protected function isAccessDeniedCode($code): bool
|
||||
{
|
||||
return $code === static::MYSQL_ACCESS_DENIED_CODE;
|
||||
}
|
||||
|
||||
protected function isValetInstalled(): bool
|
||||
{
|
||||
return file_exists('/usr/local/bin/valet');
|
||||
}
|
||||
|
||||
protected function usingCorrectDefaultCredentials(): bool
|
||||
{
|
||||
return env('DB_USERNAME') === 'root' && env('DB_PASSWORD') === '';
|
||||
}
|
||||
}
|
||||
79
vendor/facade/ignition/src/SolutionProviders/InvalidRouteActionSolutionProvider.php
vendored
Normal file
79
vendor/facade/ignition/src/SolutionProviders/InvalidRouteActionSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Support\ComposerClassMap;
|
||||
use Facade\Ignition\Support\StringComparator;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
use UnexpectedValueException;
|
||||
|
||||
class InvalidRouteActionSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
protected const REGEX = '/\[([a-zA-Z\\\\]+)\]/m';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof UnexpectedValueException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! preg_match(self::REGEX, $throwable->getMessage(), $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Str::startsWith($throwable->getMessage(), 'Invalid route action: ');
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
preg_match(self::REGEX, $throwable->getMessage(), $matches);
|
||||
|
||||
$invalidController = $matches[1] ?? null;
|
||||
|
||||
$suggestedController = $this->findRelatedController($invalidController);
|
||||
|
||||
if ($suggestedController === $invalidController) {
|
||||
return [
|
||||
BaseSolution::create("`{$invalidController}` is not invokable.")
|
||||
->setSolutionDescription("The controller class `{$invalidController}` is not invokable. Did you forget to add the `__invoke` method or is the controller's method missing in your routes file?"),
|
||||
];
|
||||
}
|
||||
|
||||
if ($suggestedController) {
|
||||
return [
|
||||
BaseSolution::create("`{$invalidController}` was not found.")
|
||||
->setSolutionDescription("Controller class `{$invalidController}` for one of your routes was not found. Did you mean `{$suggestedController}`?"),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
BaseSolution::create("`{$invalidController}` was not found.")
|
||||
->setSolutionDescription("Controller class `{$invalidController}` for one of your routes was not found. Are you sure this controller exists and is imported correctly?"),
|
||||
];
|
||||
}
|
||||
|
||||
protected function findRelatedController(string $invalidController): ?string
|
||||
{
|
||||
$composerClassMap = app(ComposerClassMap::class);
|
||||
|
||||
$controllers = collect($composerClassMap->listClasses())
|
||||
->filter(function (string $_file, string $fqcn) {
|
||||
return Str::endsWith($fqcn, 'Controller');
|
||||
})
|
||||
->mapWithKeys(function (string $_file, string $fqcn) {
|
||||
return [$fqcn => class_basename($fqcn)];
|
||||
})
|
||||
->toArray();
|
||||
|
||||
$basenameMatch = StringComparator::findClosestMatch($controllers, $invalidController, 4);
|
||||
|
||||
$controllers = array_flip($controllers);
|
||||
|
||||
$fqcnMatch = StringComparator::findClosestMatch($controllers, $invalidController, 4);
|
||||
|
||||
return $fqcnMatch ?? $basenameMatch;
|
||||
}
|
||||
}
|
||||
41
vendor/facade/ignition/src/SolutionProviders/LazyLoadingViolationSolutionProvider.php
vendored
Normal file
41
vendor/facade/ignition/src/SolutionProviders/LazyLoadingViolationSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Support\LaravelVersion;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Database\LazyLoadingViolationException;
|
||||
use Throwable;
|
||||
|
||||
class LazyLoadingViolationSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if ($throwable instanceof LazyLoadingViolationException) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $previous = $throwable->getPrevious()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $previous instanceof LazyLoadingViolationException;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
$majorVersion = LaravelVersion::major();
|
||||
|
||||
return [BaseSolution::create(
|
||||
'Lazy loading was disabled to detect N+1 problems'
|
||||
)
|
||||
->setSolutionDescription(
|
||||
'Either avoid lazy loading the relation or allow lazy loading.'
|
||||
)
|
||||
->setDocumentationLinks([
|
||||
'Read the docs on preventing lazy loading' => "https://laravel.com/docs/{$majorVersion}.x/eloquent-relationships#preventing-lazy-loading",
|
||||
'Watch a video on how to deal with the N+1 problem' => 'https://www.youtube.com/watch?v=ZE7KBeraVpc',
|
||||
]),];
|
||||
}
|
||||
}
|
||||
75
vendor/facade/ignition/src/SolutionProviders/MergeConflictSolutionProvider.php
vendored
Normal file
75
vendor/facade/ignition/src/SolutionProviders/MergeConflictSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Str;
|
||||
use ParseError;
|
||||
use Throwable;
|
||||
|
||||
class MergeConflictSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! ($throwable instanceof ParseError)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->hasMergeConflictExceptionMessage($throwable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = file_get_contents($throwable->getFile());
|
||||
|
||||
if (strpos($file, '=======') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($file, '>>>>>>>') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
$file = file_get_contents($throwable->getFile());
|
||||
preg_match('/\>\>\>\>\>\>\> (.*?)\n/', $file, $matches);
|
||||
$source = $matches[1];
|
||||
|
||||
$target = $this->getCurrentBranch(basename($throwable->getFile()));
|
||||
|
||||
return [
|
||||
BaseSolution::create("Merge conflict from branch '$source' into $target")
|
||||
->setSolutionDescription('You have a Git merge conflict. To undo your merge do `git reset --hard HEAD`'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getCurrentBranch(string $directory): string
|
||||
{
|
||||
$branch = "'".trim(shell_exec("cd {$directory}; git branch | grep \\* | cut -d ' ' -f2"))."'";
|
||||
|
||||
if ($branch === "''") {
|
||||
$branch = 'current branch';
|
||||
}
|
||||
|
||||
return $branch;
|
||||
}
|
||||
|
||||
protected function hasMergeConflictExceptionMessage(Throwable $throwable): bool
|
||||
{
|
||||
// For PHP 7.x and below
|
||||
if (Str::startsWith($throwable->getMessage(), 'syntax error, unexpected \'<<\'')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For PHP 8+
|
||||
if (Str::startsWith($throwable->getMessage(), 'syntax error, unexpected token "<<"')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
25
vendor/facade/ignition/src/SolutionProviders/MissingAppKeySolutionProvider.php
vendored
Normal file
25
vendor/facade/ignition/src/SolutionProviders/MissingAppKeySolutionProvider.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\GenerateAppKeySolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class MissingAppKeySolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof RuntimeException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $throwable->getMessage() === 'No application encryption key has been specified.';
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new GenerateAppKeySolution()];
|
||||
}
|
||||
}
|
||||
35
vendor/facade/ignition/src/SolutionProviders/MissingColumnSolutionProvider.php
vendored
Normal file
35
vendor/facade/ignition/src/SolutionProviders/MissingColumnSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\RunMigrationsSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Throwable;
|
||||
|
||||
class MissingColumnSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
/**
|
||||
* See https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html#error_er_bad_field_error.
|
||||
*/
|
||||
public const MYSQL_BAD_FIELD_CODE = '42S22';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof QueryException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isBadTableErrorCode($throwable->getCode());
|
||||
}
|
||||
|
||||
protected function isBadTableErrorCode($code): bool
|
||||
{
|
||||
return $code === static::MYSQL_BAD_FIELD_CODE;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new RunMigrationsSolution('A column was not found')];
|
||||
}
|
||||
}
|
||||
48
vendor/facade/ignition/src/SolutionProviders/MissingImportSolutionProvider.php
vendored
Normal file
48
vendor/facade/ignition/src/SolutionProviders/MissingImportSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\SuggestImportSolution;
|
||||
use Facade\Ignition\Support\ComposerClassMap;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Throwable;
|
||||
|
||||
class MissingImportSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
/** @var string */
|
||||
protected $foundClass;
|
||||
|
||||
/** @var \Facade\Ignition\Support\ComposerClassMap */
|
||||
protected $composerClassMap;
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
$pattern = '/Class \'([^\s]+)\' not found/m';
|
||||
|
||||
if (! preg_match($pattern, $throwable->getMessage(), $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$class = $matches[1];
|
||||
|
||||
$this->composerClassMap = new ComposerClassMap();
|
||||
|
||||
$this->search($class);
|
||||
|
||||
return ! is_null($this->foundClass);
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new SuggestImportSolution($this->foundClass)];
|
||||
}
|
||||
|
||||
protected function search(string $missingClass)
|
||||
{
|
||||
$this->foundClass = $this->composerClassMap->searchClassMap($missingClass);
|
||||
|
||||
if (is_null($this->foundClass)) {
|
||||
$this->foundClass = $this->composerClassMap->searchPsrMaps($missingClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
vendor/facade/ignition/src/SolutionProviders/MissingLivewireComponentSolutionProvider.php
vendored
Normal file
42
vendor/facade/ignition/src/SolutionProviders/MissingLivewireComponentSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\LivewireDiscoverSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Livewire\Exceptions\ComponentNotFoundException;
|
||||
use Livewire\LivewireComponentsFinder;
|
||||
use Throwable;
|
||||
|
||||
class MissingLivewireComponentSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $this->livewireIsInstalled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $throwable instanceof ComponentNotFoundException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new LivewireDiscoverSolution('A Livewire component was not found')];
|
||||
}
|
||||
|
||||
public function livewireIsInstalled(): bool
|
||||
{
|
||||
if (! class_exists(ComponentNotFoundException::class)) {
|
||||
return false;
|
||||
}
|
||||
if (! class_exists(LivewireComponentsFinder::class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
24
vendor/facade/ignition/src/SolutionProviders/MissingMixManifestSolutionProvider.php
vendored
Normal file
24
vendor/facade/ignition/src/SolutionProviders/MissingMixManifestSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
class MissingMixManifestSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
return Str::startsWith($throwable->getMessage(), 'The Mix manifest does not exist');
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [
|
||||
BaseSolution::create('Missing Mix Manifest File')
|
||||
->setSolutionDescription('Did you forget to run `npm ci && npm run dev`?'),
|
||||
];
|
||||
}
|
||||
}
|
||||
58
vendor/facade/ignition/src/SolutionProviders/MissingPackageSolutionProvider.php
vendored
Normal file
58
vendor/facade/ignition/src/SolutionProviders/MissingPackageSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\MissingPackageSolution;
|
||||
use Facade\Ignition\Support\Packagist\Package;
|
||||
use Facade\Ignition\Support\Packagist\Packagist;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
class MissingPackageSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
/** @var \Facade\Ignition\Support\Packagist\Package|null */
|
||||
protected $package;
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
$pattern = '/Class \'([^\s]+)\' not found/m';
|
||||
|
||||
if (! preg_match($pattern, $throwable->getMessage(), $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$class = $matches[1];
|
||||
|
||||
if (Str::startsWith($class, app()->getNamespace())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->package = $this->findPackageFromClassName($class);
|
||||
|
||||
return ! is_null($this->package);
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new MissingPackageSolution($this->package)];
|
||||
}
|
||||
|
||||
protected function findPackageFromClassName(string $missingClassName): ?Package
|
||||
{
|
||||
if (! $package = $this->findComposerPackageForClassName($missingClassName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $package->hasNamespaceThatContainsClassName($missingClassName)
|
||||
? $package
|
||||
: null;
|
||||
}
|
||||
|
||||
protected function findComposerPackageForClassName(string $className): ?Package
|
||||
{
|
||||
$packages = Packagist::findPackagesForClassName($className);
|
||||
|
||||
return $packages[0] ?? null;
|
||||
}
|
||||
}
|
||||
63
vendor/facade/ignition/src/SolutionProviders/RouteNotDefinedSolutionProvider.php
vendored
Normal file
63
vendor/facade/ignition/src/SolutionProviders/RouteNotDefinedSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Exceptions\ViewException;
|
||||
use Facade\Ignition\Support\StringComparator;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Throwable;
|
||||
|
||||
class RouteNotDefinedSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
protected const REGEX = '/Route \[(.*)\] not defined/m';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (version_compare(Application::VERSION, '6.0.0', '>=')) {
|
||||
if (! $throwable instanceof RouteNotFoundException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (version_compare(Application::VERSION, '6.0.0', '<')) {
|
||||
if (! $throwable instanceof InvalidArgumentException && ! $throwable instanceof ViewException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (bool)preg_match(self::REGEX, $throwable->getMessage(), $matches);
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
preg_match(self::REGEX, $throwable->getMessage(), $matches);
|
||||
|
||||
$missingRoute = $matches[1] ?? null;
|
||||
|
||||
$suggestedRoute = $this->findRelatedRoute($missingRoute);
|
||||
|
||||
if ($suggestedRoute) {
|
||||
return [
|
||||
BaseSolution::create("{$missingRoute} was not defined.")
|
||||
->setSolutionDescription("Did you mean `{$suggestedRoute}`?"),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
BaseSolution::create("{$missingRoute} was not defined.")
|
||||
->setSolutionDescription('Are you sure that the route is defined'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function findRelatedRoute(string $missingRoute): ?string
|
||||
{
|
||||
Route::getRoutes()->refreshNameLookups();
|
||||
|
||||
return StringComparator::findClosestMatch(array_keys(Route::getRoutes()->getRoutesByName()), $missingRoute);
|
||||
}
|
||||
}
|
||||
30
vendor/facade/ignition/src/SolutionProviders/RunningLaravelDuskInProductionProvider.php
vendored
Normal file
30
vendor/facade/ignition/src/SolutionProviders/RunningLaravelDuskInProductionProvider.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Exception;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Throwable;
|
||||
|
||||
class RunningLaravelDuskInProductionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof Exception) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $throwable->getMessage() === 'It is unsafe to run Dusk in production.';
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [
|
||||
BaseSolution::create('Laravel Dusk should not be run in production.')
|
||||
->setSolutionDescription('Install the dependencies with the `--no-dev` flag.'),
|
||||
BaseSolution::create('Laravel Dusk can be run in other environments.')
|
||||
->setSolutionDescription('Consider setting the `APP_ENV` to something other than `production` like `local` for example.'),
|
||||
];
|
||||
}
|
||||
}
|
||||
95
vendor/facade/ignition/src/SolutionProviders/SolutionProviderRepository.php
vendored
Normal file
95
vendor/facade/ignition/src/SolutionProviders/SolutionProviderRepository.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Facade\IgnitionContracts\ProvidesSolution;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
use Facade\IgnitionContracts\SolutionProviderRepository as SolutionProviderRepositoryContract;
|
||||
use Illuminate\Support\Collection;
|
||||
use Throwable;
|
||||
|
||||
class SolutionProviderRepository implements SolutionProviderRepositoryContract
|
||||
{
|
||||
/** @var \Illuminate\Support\Collection */
|
||||
protected $solutionProviders;
|
||||
|
||||
public function __construct(array $solutionProviders = [])
|
||||
{
|
||||
$this->solutionProviders = Collection::make($solutionProviders);
|
||||
}
|
||||
|
||||
public function registerSolutionProvider(string $solutionProviderClass): SolutionProviderRepositoryContract
|
||||
{
|
||||
$this->solutionProviders->push($solutionProviderClass);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function registerSolutionProviders(array $solutionProviderClasses): SolutionProviderRepositoryContract
|
||||
{
|
||||
$this->solutionProviders = $this->solutionProviders->merge($solutionProviderClasses);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSolutionsForThrowable(Throwable $throwable): array
|
||||
{
|
||||
$solutions = [];
|
||||
|
||||
if ($throwable instanceof Solution) {
|
||||
$solutions[] = $throwable;
|
||||
}
|
||||
|
||||
if ($throwable instanceof ProvidesSolution) {
|
||||
$solutions[] = $throwable->getSolution();
|
||||
}
|
||||
|
||||
$providedSolutions = $this->solutionProviders
|
||||
->filter(function (string $solutionClass) {
|
||||
if (! in_array(HasSolutionsForThrowable::class, class_implements($solutionClass))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array($solutionClass, config('ignition.ignored_solution_providers', []))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
->map(function (string $solutionClass) {
|
||||
return app($solutionClass);
|
||||
})
|
||||
->filter(function (HasSolutionsForThrowable $solutionProvider) use ($throwable) {
|
||||
try {
|
||||
return $solutionProvider->canSolve($throwable);
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->map(function (HasSolutionsForThrowable $solutionProvider) use ($throwable) {
|
||||
try {
|
||||
return $solutionProvider->getSolutions($throwable);
|
||||
} catch (Throwable $e) {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
->flatten()
|
||||
->toArray();
|
||||
|
||||
return array_merge($solutions, $providedSolutions);
|
||||
}
|
||||
|
||||
public function getSolutionForClass(string $solutionClass): ?Solution
|
||||
{
|
||||
if (! class_exists($solutionClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! in_array(Solution::class, class_implements($solutionClass))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return app($solutionClass);
|
||||
}
|
||||
}
|
||||
35
vendor/facade/ignition/src/SolutionProviders/TableNotFoundSolutionProvider.php
vendored
Normal file
35
vendor/facade/ignition/src/SolutionProviders/TableNotFoundSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\RunMigrationsSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Throwable;
|
||||
|
||||
class TableNotFoundSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
/**
|
||||
* See https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html#error_er_bad_table_error.
|
||||
*/
|
||||
public const MYSQL_BAD_TABLE_CODE = '42S02';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof QueryException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isBadTableErrorCode($throwable->getCode());
|
||||
}
|
||||
|
||||
protected function isBadTableErrorCode($code): bool
|
||||
{
|
||||
return $code === static::MYSQL_BAD_TABLE_CODE;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [new RunMigrationsSolution('A table was not found')];
|
||||
}
|
||||
}
|
||||
48
vendor/facade/ignition/src/SolutionProviders/UndefinedLivewireMethodSolutionProvider.php
vendored
Normal file
48
vendor/facade/ignition/src/SolutionProviders/UndefinedLivewireMethodSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\SuggestLivewireMethodNameSolution;
|
||||
use Facade\Ignition\Support\LivewireComponentParser;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Livewire\Exceptions\MethodNotFoundException;
|
||||
use Throwable;
|
||||
|
||||
class UndefinedLivewireMethodSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
return $throwable instanceof MethodNotFoundException;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
['methodName' => $methodName, 'component' => $component] = $this->getMethodAndComponent($throwable);
|
||||
|
||||
if ($methodName === null || $component === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$parsed = LivewireComponentParser::create($component);
|
||||
|
||||
return $parsed->getMethodNamesLike($methodName)
|
||||
->map(function (string $suggested) use ($parsed, $methodName) {
|
||||
return new SuggestLivewireMethodNameSolution(
|
||||
$methodName,
|
||||
$parsed->getComponentClass(),
|
||||
$suggested
|
||||
);
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
protected function getMethodAndComponent(Throwable $throwable): array
|
||||
{
|
||||
preg_match_all('/\[([\d\w\-_]*)\]/m', $throwable->getMessage(), $matches, PREG_SET_ORDER);
|
||||
|
||||
return [
|
||||
'methodName' => $matches[0][1] ?? null,
|
||||
'component' => $matches[1][1] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
49
vendor/facade/ignition/src/SolutionProviders/UndefinedLivewirePropertySolutionProvider.php
vendored
Normal file
49
vendor/facade/ignition/src/SolutionProviders/UndefinedLivewirePropertySolutionProvider.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Solutions\SuggestLivewirePropertyNameSolution;
|
||||
use Facade\Ignition\Support\LivewireComponentParser;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Livewire\Exceptions\PropertyNotFoundException;
|
||||
use Livewire\Exceptions\PublicPropertyNotFoundException;
|
||||
use Throwable;
|
||||
|
||||
class UndefinedLivewirePropertySolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
return $throwable instanceof PropertyNotFoundException || $throwable instanceof PublicPropertyNotFoundException;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
['variable' => $variable, 'component' => $component] = $this->getMethodAndComponent($throwable);
|
||||
|
||||
if ($variable === null || $component === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$parsed = LivewireComponentParser::create($component);
|
||||
|
||||
return $parsed->getPropertyNamesLike($variable)
|
||||
->map(function (string $suggested) use ($parsed, $variable) {
|
||||
return new SuggestLivewirePropertyNameSolution(
|
||||
$variable,
|
||||
$parsed->getComponentClass(),
|
||||
'$'.$suggested
|
||||
);
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
protected function getMethodAndComponent(Throwable $throwable): array
|
||||
{
|
||||
preg_match_all('/\[([\d\w\-_\$]*)\]/m', $throwable->getMessage(), $matches, PREG_SET_ORDER, 0);
|
||||
|
||||
return [
|
||||
'variable' => $matches[0][1] ?? null,
|
||||
'component' => $matches[1][1] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
98
vendor/facade/ignition/src/SolutionProviders/UndefinedPropertySolutionProvider.php
vendored
Normal file
98
vendor/facade/ignition/src/SolutionProviders/UndefinedPropertySolutionProvider.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use ErrorException;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Collection;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use Throwable;
|
||||
|
||||
class UndefinedPropertySolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
protected const REGEX = '/([a-zA-Z\\\\]+)::\$([a-zA-Z]+)/m';
|
||||
protected const MINIMUM_SIMILARITY = 80;
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof ErrorException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_null($this->getClassAndPropertyFromExceptionMessage($throwable->getMessage()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->similarPropertyExists($throwable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [
|
||||
BaseSolution::create('Unknown Property')
|
||||
->setSolutionDescription($this->getSolutionDescription($throwable)),
|
||||
];
|
||||
}
|
||||
|
||||
public function getSolutionDescription(Throwable $throwable): string
|
||||
{
|
||||
if (! $this->canSolve($throwable) || ! $this->similarPropertyExists($throwable)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
extract($this->getClassAndPropertyFromExceptionMessage($throwable->getMessage()), EXTR_OVERWRITE);
|
||||
|
||||
$possibleProperty = $this->findPossibleProperty($class, $property);
|
||||
|
||||
return "Did you mean {$class}::\${$possibleProperty->name} ?";
|
||||
}
|
||||
|
||||
protected function similarPropertyExists(Throwable $throwable)
|
||||
{
|
||||
extract($this->getClassAndPropertyFromExceptionMessage($throwable->getMessage()), EXTR_OVERWRITE);
|
||||
|
||||
$possibleProperty = $this->findPossibleProperty($class, $property);
|
||||
|
||||
return $possibleProperty !== null;
|
||||
}
|
||||
|
||||
protected function getClassAndPropertyFromExceptionMessage(string $message): ?array
|
||||
{
|
||||
if (! preg_match(self::REGEX, $message, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'class' => $matches[1],
|
||||
'property' => $matches[2],
|
||||
];
|
||||
}
|
||||
|
||||
protected function findPossibleProperty(string $class, string $invalidPropertyName)
|
||||
{
|
||||
return $this->getAvailableProperties($class)
|
||||
->sortByDesc(function (ReflectionProperty $property) use ($invalidPropertyName) {
|
||||
similar_text($invalidPropertyName, $property->name, $percentage);
|
||||
|
||||
return $percentage;
|
||||
})
|
||||
->filter(function (ReflectionProperty $property) use ($invalidPropertyName) {
|
||||
similar_text($invalidPropertyName, $property->name, $percentage);
|
||||
|
||||
return $percentage >= self::MINIMUM_SIMILARITY;
|
||||
})->first();
|
||||
}
|
||||
|
||||
protected function getAvailableProperties($class): Collection
|
||||
{
|
||||
$class = new ReflectionClass($class);
|
||||
|
||||
return Collection::make($class->getProperties());
|
||||
}
|
||||
}
|
||||
95
vendor/facade/ignition/src/SolutionProviders/UndefinedVariableSolutionProvider.php
vendored
Normal file
95
vendor/facade/ignition/src/SolutionProviders/UndefinedVariableSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Exceptions\ViewException;
|
||||
use Facade\Ignition\Solutions\MakeViewVariableOptionalSolution;
|
||||
use Facade\Ignition\Solutions\SuggestCorrectVariableNameSolution;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Throwable;
|
||||
|
||||
class UndefinedVariableSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
private $variableName;
|
||||
|
||||
private $viewFile;
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof ViewException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getNameAndView($throwable) !== null;
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
$solutions = [];
|
||||
|
||||
extract($this->getNameAndView($throwable));
|
||||
|
||||
if (! isset($variableName)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$solutions = $this->findCorrectVariableSolutions($throwable, $variableName, $viewFile);
|
||||
$solutions[] = $this->findOptionalVariableSolution($variableName, $viewFile);
|
||||
|
||||
return $solutions;
|
||||
}
|
||||
|
||||
protected function findCorrectVariableSolutions(
|
||||
ViewException $throwable,
|
||||
string $variableName,
|
||||
string $viewFile
|
||||
): array {
|
||||
return collect($throwable->getViewData())
|
||||
->map(function ($value, $key) use ($variableName) {
|
||||
similar_text($variableName, $key, $percentage);
|
||||
|
||||
return ['match' => $percentage, 'value' => $value];
|
||||
})
|
||||
->sortByDesc('match')->filter(function ($var) {
|
||||
return $var['match'] > 40;
|
||||
})
|
||||
->keys()
|
||||
->map(function ($suggestion) use ($variableName, $viewFile) {
|
||||
return new SuggestCorrectVariableNameSolution($variableName, $viewFile, $suggestion);
|
||||
})
|
||||
->map(function ($solution) {
|
||||
return $solution->isRunnable()
|
||||
? $solution
|
||||
: BaseSolution::create($solution->getSolutionTitle())
|
||||
->setSolutionDescription($solution->getSolutionDescription());
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
protected function findOptionalVariableSolution(string $variableName, string $viewFile)
|
||||
{
|
||||
$optionalSolution = new MakeViewVariableOptionalSolution($variableName, $viewFile);
|
||||
|
||||
return $optionalSolution->isRunnable()
|
||||
? $optionalSolution
|
||||
: BaseSolution::create($optionalSolution->getSolutionTitle())
|
||||
->setSolutionDescription($optionalSolution->getSolutionDescription());
|
||||
}
|
||||
|
||||
protected function getNameAndView(Throwable $throwable): ?array
|
||||
{
|
||||
$pattern = '/Undefined variable:? (.*?) \(View: (.*?)\)/';
|
||||
|
||||
preg_match($pattern, $throwable->getMessage(), $matches);
|
||||
|
||||
if (count($matches) === 3) {
|
||||
[, $variableName, $viewFile] = $matches;
|
||||
$variableName = ltrim($variableName, '$');
|
||||
|
||||
return compact('variableName', 'viewFile');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
83
vendor/facade/ignition/src/SolutionProviders/UnknownValidationSolutionProvider.php
vendored
Normal file
83
vendor/facade/ignition/src/SolutionProviders/UnknownValidationSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Facade\Ignition\Support\StringComparator;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Validator;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use Throwable;
|
||||
|
||||
class UnknownValidationSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
protected const REGEX = '/Illuminate\\\\Validation\\\\Validator::(?P<method>validate(?!(Attribute|UsingCustomRule))[A-Z][a-zA-Z]+)/m';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof BadMethodCallException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! is_null($this->getMethodFromExceptionMessage($throwable->getMessage()));
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
return [
|
||||
BaseSolution::create('Unknown Validation Rule')
|
||||
->setSolutionDescription($this->getSolutionDescription($throwable)),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getSolutionDescription(Throwable $throwable): string
|
||||
{
|
||||
$method = $this->getMethodFromExceptionMessage($throwable->getMessage());
|
||||
|
||||
$possibleMethod = StringComparator::findSimilarText(
|
||||
$this->getAvailableMethods()->toArray(),
|
||||
$method
|
||||
);
|
||||
|
||||
if (empty($possibleMethod)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$rule = Str::snake(str_replace('validate', '', $possibleMethod));
|
||||
|
||||
return "Did you mean `{$rule}` ?";
|
||||
}
|
||||
|
||||
protected function getMethodFromExceptionMessage(string $message): ?string
|
||||
{
|
||||
if (! preg_match(self::REGEX, $message, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $matches['method'];
|
||||
}
|
||||
|
||||
protected function getAvailableMethods(): Collection
|
||||
{
|
||||
$class = new ReflectionClass(Validator::class);
|
||||
|
||||
$extensions = Collection::make((app('validator')->make([], []))->extensions)
|
||||
->keys()
|
||||
->map(function (string $extension) {
|
||||
return 'validate'.Str::studly($extension);
|
||||
});
|
||||
|
||||
return Collection::make($class->getMethods())
|
||||
->filter(function (ReflectionMethod $method) {
|
||||
return preg_match('/(validate(?!(Attribute|UsingCustomRule))[A-Z][a-zA-Z]+)/', $method->name);
|
||||
})
|
||||
->map(function (ReflectionMethod $method) {
|
||||
return $method->name;
|
||||
})
|
||||
->merge($extensions);
|
||||
}
|
||||
}
|
||||
124
vendor/facade/ignition/src/SolutionProviders/ViewNotFoundSolutionProvider.php
vendored
Normal file
124
vendor/facade/ignition/src/SolutionProviders/ViewNotFoundSolutionProvider.php
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\SolutionProviders;
|
||||
|
||||
use Facade\Ignition\Exceptions\ViewException;
|
||||
use Facade\Ignition\Support\StringComparator;
|
||||
use Facade\IgnitionContracts\BaseSolution;
|
||||
use Facade\IgnitionContracts\HasSolutionsForThrowable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use InvalidArgumentException;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Throwable;
|
||||
|
||||
class ViewNotFoundSolutionProvider implements HasSolutionsForThrowable
|
||||
{
|
||||
protected const REGEX = '/View \[(.*)\] not found/m';
|
||||
|
||||
public function canSolve(Throwable $throwable): bool
|
||||
{
|
||||
if (! $throwable instanceof InvalidArgumentException && ! $throwable instanceof ViewException) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)preg_match(self::REGEX, $throwable->getMessage(), $matches);
|
||||
}
|
||||
|
||||
public function getSolutions(Throwable $throwable): array
|
||||
{
|
||||
preg_match(self::REGEX, $throwable->getMessage(), $matches);
|
||||
|
||||
$missingView = $matches[1] ?? null;
|
||||
|
||||
$suggestedView = $this->findRelatedView($missingView);
|
||||
|
||||
if ($suggestedView == $missingView) {
|
||||
return [
|
||||
BaseSolution::create("{$missingView} was not found.")
|
||||
->setSolutionDescription('View names should not contain the . character!'),
|
||||
];
|
||||
}
|
||||
|
||||
if ($suggestedView) {
|
||||
return [
|
||||
BaseSolution::create("{$missingView} was not found.")
|
||||
->setSolutionDescription("Did you mean `{$suggestedView}`?"),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
BaseSolution::create("{$missingView} was not found.")
|
||||
->setSolutionDescription('Are you sure the view exists and is a `.blade.php` file?'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function findRelatedView(string $missingView): ?string
|
||||
{
|
||||
$views = $this->getAllViews();
|
||||
|
||||
return StringComparator::findClosestMatch($views, $missingView);
|
||||
}
|
||||
|
||||
protected function getAllViews(): array
|
||||
{
|
||||
/** @var \Illuminate\View\FileViewFinder $fileViewFinder */
|
||||
$fileViewFinder = View::getFinder();
|
||||
|
||||
$extensions = $fileViewFinder->getExtensions();
|
||||
|
||||
$viewsForHints = collect($fileViewFinder->getHints())
|
||||
->flatMap(function ($paths, string $namespace) use ($extensions) {
|
||||
$paths = Arr::wrap($paths);
|
||||
|
||||
return collect($paths)
|
||||
->flatMap(function (string $path) use ($extensions) {
|
||||
return $this->getViewsInPath($path, $extensions);
|
||||
})
|
||||
->map(function (string $view) use ($namespace) {
|
||||
return "{$namespace}::{$view}";
|
||||
})
|
||||
->toArray();
|
||||
});
|
||||
|
||||
$viewsForViewPaths = collect($fileViewFinder->getPaths())
|
||||
->flatMap(function (string $path) use ($extensions) {
|
||||
return $this->getViewsInPath($path, $extensions);
|
||||
});
|
||||
|
||||
return $viewsForHints->merge($viewsForViewPaths)->toArray();
|
||||
}
|
||||
|
||||
protected function getViewsInPath(string $path, array $extensions): array
|
||||
{
|
||||
$filePatterns = array_map(function (string $extension) {
|
||||
return "*.{$extension}";
|
||||
}, $extensions);
|
||||
|
||||
$extensionsWithDots = array_map(function (string $extension) {
|
||||
return ".{$extension}";
|
||||
}, $extensions);
|
||||
|
||||
$files = (new Finder())
|
||||
->in($path)
|
||||
->files();
|
||||
|
||||
foreach ($filePatterns as $filePattern) {
|
||||
$files->name($filePattern);
|
||||
}
|
||||
|
||||
$views = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ($file instanceof SplFileInfo) {
|
||||
$view = $file->getRelativePathname();
|
||||
$view = str_replace($extensionsWithDots, '', $view);
|
||||
$view = str_replace('/', '.', $view);
|
||||
$views[] = $view;
|
||||
}
|
||||
}
|
||||
|
||||
return $views;
|
||||
}
|
||||
}
|
||||
46
vendor/facade/ignition/src/Solutions/GenerateAppKeySolution.php
vendored
Normal file
46
vendor/facade/ignition/src/Solutions/GenerateAppKeySolution.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class GenerateAppKeySolution implements RunnableSolution
|
||||
{
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return 'Your app key is missing';
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [
|
||||
'Laravel installation' => 'https://laravel.com/docs/master/installation#configuration',
|
||||
];
|
||||
}
|
||||
|
||||
public function getSolutionActionDescription(): string
|
||||
{
|
||||
return 'Generate your application encryption key using `php artisan key:generate`.';
|
||||
}
|
||||
|
||||
public function getRunButtonText(): string
|
||||
{
|
||||
return 'Generate app key';
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getRunParameters(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function run(array $parameters = [])
|
||||
{
|
||||
Artisan::call('key:generate');
|
||||
}
|
||||
}
|
||||
53
vendor/facade/ignition/src/Solutions/LivewireDiscoverSolution.php
vendored
Normal file
53
vendor/facade/ignition/src/Solutions/LivewireDiscoverSolution.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Livewire\LivewireComponentsFinder;
|
||||
|
||||
class LivewireDiscoverSolution implements RunnableSolution
|
||||
{
|
||||
private $customTitle;
|
||||
|
||||
public function __construct($customTitle = '')
|
||||
{
|
||||
$this->customTitle = $customTitle;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return $this->customTitle;
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return 'You might have forgotten to discover your Livewire components. You can discover your Livewire components using `php artisan livewire:discover`.';
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [
|
||||
'Livewire: Artisan Commands' => 'https://laravel-livewire.com/docs/2.x/artisan-commands',
|
||||
];
|
||||
}
|
||||
|
||||
public function getRunParameters(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionActionDescription(): string
|
||||
{
|
||||
return 'Pressing the button below will try to discover your Livewire components.';
|
||||
}
|
||||
|
||||
public function getRunButtonText(): string
|
||||
{
|
||||
return 'Run livewire:discover';
|
||||
}
|
||||
|
||||
public function run(array $parameters = [])
|
||||
{
|
||||
app(LivewireComponentsFinder::class)->build();
|
||||
}
|
||||
}
|
||||
122
vendor/facade/ignition/src/Solutions/MakeViewVariableOptionalSolution.php
vendored
Normal file
122
vendor/facade/ignition/src/Solutions/MakeViewVariableOptionalSolution.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MakeViewVariableOptionalSolution implements RunnableSolution
|
||||
{
|
||||
/** @var string */
|
||||
private $variableName;
|
||||
|
||||
/** @var string */
|
||||
private $viewFile;
|
||||
|
||||
public function __construct($variableName = null, $viewFile = null)
|
||||
{
|
||||
$this->variableName = $variableName;
|
||||
$this->viewFile = $viewFile;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return "$$this->variableName is undefined";
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionActionDescription(): string
|
||||
{
|
||||
$output = [
|
||||
'Make the variable optional in the blade template.',
|
||||
"Replace `{{ $$this->variableName }}` with `{{ $$this->variableName ?? '' }}`",
|
||||
];
|
||||
|
||||
return implode(PHP_EOL, $output);
|
||||
}
|
||||
|
||||
public function getRunButtonText(): string
|
||||
{
|
||||
return 'Make variable optional';
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getRunParameters(): array
|
||||
{
|
||||
return [
|
||||
'variableName' => $this->variableName,
|
||||
'viewFile' => $this->viewFile,
|
||||
];
|
||||
}
|
||||
|
||||
public function isRunnable(array $parameters = [])
|
||||
{
|
||||
return $this->makeOptional($this->getRunParameters()) !== false;
|
||||
}
|
||||
|
||||
public function run(array $parameters = [])
|
||||
{
|
||||
$output = $this->makeOptional($parameters);
|
||||
if ($output !== false) {
|
||||
file_put_contents($parameters['viewFile'], $output);
|
||||
}
|
||||
}
|
||||
|
||||
protected function isSafePath(string $path): bool
|
||||
{
|
||||
if (! Str::startsWith($path, ['/', './'])) {
|
||||
return false;
|
||||
}
|
||||
if (! Str::endsWith($path, '.blade.php')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function makeOptional(array $parameters = [])
|
||||
{
|
||||
if (! $this->isSafePath($parameters['viewFile'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$originalContents = file_get_contents($parameters['viewFile']);
|
||||
$newContents = str_replace('$'.$parameters['variableName'], '$'.$parameters['variableName']." ?? ''", $originalContents);
|
||||
|
||||
$originalTokens = token_get_all(Blade::compileString($originalContents));
|
||||
$newTokens = token_get_all(Blade::compileString($newContents));
|
||||
|
||||
$expectedTokens = $this->generateExpectedTokens($originalTokens, $parameters['variableName']);
|
||||
|
||||
if ($expectedTokens !== $newTokens) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $newContents;
|
||||
}
|
||||
|
||||
protected function generateExpectedTokens(array $originalTokens, string $variableName): array
|
||||
{
|
||||
$expectedTokens = [];
|
||||
foreach ($originalTokens as $token) {
|
||||
$expectedTokens[] = $token;
|
||||
if ($token[0] === T_VARIABLE && $token[1] === '$'.$variableName) {
|
||||
$expectedTokens[] = [T_WHITESPACE, ' ', $token[2]];
|
||||
$expectedTokens[] = [T_COALESCE, '??', $token[2]];
|
||||
$expectedTokens[] = [T_WHITESPACE, ' ', $token[2]];
|
||||
$expectedTokens[] = [T_CONSTANT_ENCAPSED_STRING, "''", $token[2]];
|
||||
}
|
||||
}
|
||||
|
||||
return $expectedTokens;
|
||||
}
|
||||
}
|
||||
42
vendor/facade/ignition/src/Solutions/MissingPackageSolution.php
vendored
Normal file
42
vendor/facade/ignition/src/Solutions/MissingPackageSolution.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\Ignition\Support\Packagist\Package;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class MissingPackageSolution implements Solution
|
||||
{
|
||||
/** @var Package */
|
||||
protected $possiblePackage;
|
||||
|
||||
public function __construct(Package $possiblePackage)
|
||||
{
|
||||
$this->possiblePackage = $possiblePackage;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return 'A composer dependency is missing';
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
$output = [
|
||||
'You might be missing a composer dependency.',
|
||||
'A possible package that was found is `'.$this->possiblePackage->name.'`.',
|
||||
'',
|
||||
'See if this is the package that you need and install it via `composer require '.$this->possiblePackage->name.'`.',
|
||||
];
|
||||
|
||||
return implode(PHP_EOL, $output);
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [
|
||||
'Git repository' => $this->possiblePackage->repository,
|
||||
'Package on Packagist' => $this->possiblePackage->url,
|
||||
];
|
||||
}
|
||||
}
|
||||
53
vendor/facade/ignition/src/Solutions/RunMigrationsSolution.php
vendored
Normal file
53
vendor/facade/ignition/src/Solutions/RunMigrationsSolution.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class RunMigrationsSolution implements RunnableSolution
|
||||
{
|
||||
private $customTitle;
|
||||
|
||||
public function __construct($customTitle = '')
|
||||
{
|
||||
$this->customTitle = $customTitle;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return $this->customTitle;
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return 'You might have forgotten to run your migrations. You can run your migrations using `php artisan migrate`.';
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [
|
||||
'Database: Running Migrations docs' => 'https://laravel.com/docs/master/migrations#running-migrations',
|
||||
];
|
||||
}
|
||||
|
||||
public function getRunParameters(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionActionDescription(): string
|
||||
{
|
||||
return 'Pressing the button below will try to run your migrations.';
|
||||
}
|
||||
|
||||
public function getRunButtonText(): string
|
||||
{
|
||||
return 'Run migrations';
|
||||
}
|
||||
|
||||
public function run(array $parameters = [])
|
||||
{
|
||||
Artisan::call('migrate');
|
||||
}
|
||||
}
|
||||
45
vendor/facade/ignition/src/Solutions/SolutionTransformer.php
vendored
Normal file
45
vendor/facade/ignition/src/Solutions/SolutionTransformer.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\RunnableSolution;
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Throwable;
|
||||
|
||||
class SolutionTransformer implements Arrayable
|
||||
{
|
||||
/** @var \Facade\IgnitionContracts\Solution */
|
||||
protected $solution;
|
||||
|
||||
public function __construct(Solution $solution)
|
||||
{
|
||||
$this->solution = $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(),
|
||||
'is_runnable' => $isRunnable,
|
||||
'run_button_text' => $isRunnable ? $this->solution->getRunButtonText() : '',
|
||||
'run_parameters' => $isRunnable ? $this->solution->getRunParameters() : [],
|
||||
'action_description' => $isRunnable ? $this->solution->getSolutionActionDescription() : '',
|
||||
'execute_endpoint' => $this->executeEndpoint(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function executeEndpoint(): string
|
||||
{
|
||||
try {
|
||||
return action('\Facade\Ignition\Http\Controllers\ExecuteSolutionController');
|
||||
} catch (Throwable $exception) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
44
vendor/facade/ignition/src/Solutions/SuggestCorrectVariableNameSolution.php
vendored
Normal file
44
vendor/facade/ignition/src/Solutions/SuggestCorrectVariableNameSolution.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class SuggestCorrectVariableNameSolution implements Solution
|
||||
{
|
||||
/** @var string */
|
||||
private $variableName;
|
||||
|
||||
/** @var string */
|
||||
private $viewFile;
|
||||
|
||||
/** @var string|null */
|
||||
private $suggested;
|
||||
|
||||
public function __construct($variableName = null, $viewFile = null, $suggested = null)
|
||||
{
|
||||
$this->variableName = $variableName;
|
||||
$this->viewFile = $viewFile;
|
||||
$this->suggested = $suggested;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return 'Possible typo $'.$this->variableName;
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return "Did you mean `$$this->suggested`?";
|
||||
}
|
||||
|
||||
public function isRunnable(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
31
vendor/facade/ignition/src/Solutions/SuggestImportSolution.php
vendored
Normal file
31
vendor/facade/ignition/src/Solutions/SuggestImportSolution.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class SuggestImportSolution implements Solution
|
||||
{
|
||||
/** @var string */
|
||||
protected $class;
|
||||
|
||||
public function __construct(string $class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return 'A class import is missing';
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return 'You have a missing class import. Try importing this class: `'.$this->class.'`.';
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
44
vendor/facade/ignition/src/Solutions/SuggestLivewireMethodNameSolution.php
vendored
Normal file
44
vendor/facade/ignition/src/Solutions/SuggestLivewireMethodNameSolution.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class SuggestLivewireMethodNameSolution implements Solution
|
||||
{
|
||||
/** @var string */
|
||||
private $methodName;
|
||||
|
||||
/** @var string */
|
||||
private $componentClass;
|
||||
|
||||
/** @var string|null */
|
||||
private $suggested;
|
||||
|
||||
public function __construct($methodName = null, $componentClass = null, $suggested = null)
|
||||
{
|
||||
$this->methodName = $methodName;
|
||||
$this->componentClass = $componentClass;
|
||||
$this->suggested = $suggested;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return "Possible typo `{$this->componentClass}::{$this->methodName}()`";
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return "Did you mean `{$this->suggested}()`?";
|
||||
}
|
||||
|
||||
public function isRunnable(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
44
vendor/facade/ignition/src/Solutions/SuggestLivewirePropertyNameSolution.php
vendored
Normal file
44
vendor/facade/ignition/src/Solutions/SuggestLivewirePropertyNameSolution.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Facade\Ignition\Solutions;
|
||||
|
||||
use Facade\IgnitionContracts\Solution;
|
||||
|
||||
class SuggestLivewirePropertyNameSolution implements Solution
|
||||
{
|
||||
/** @var string */
|
||||
private $variableName;
|
||||
|
||||
/** @var string */
|
||||
private $componentClass;
|
||||
|
||||
/** @var string|null */
|
||||
private $suggested;
|
||||
|
||||
public function __construct($variableName = null, $componentClass = null, $suggested = null)
|
||||
{
|
||||
$this->variableName = $variableName;
|
||||
$this->componentClass = $componentClass;
|
||||
$this->suggested = $suggested;
|
||||
}
|
||||
|
||||
public function getSolutionTitle(): string
|
||||
{
|
||||
return "Possible typo {$this->componentClass}::{$this->variableName}";
|
||||
}
|
||||
|
||||
public function getDocumentationLinks(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSolutionDescription(): string
|
||||
{
|
||||
return "Did you mean `$this->suggested`?";
|
||||
}
|
||||
|
||||
public function isRunnable(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user