From b4a582ecacec16d22c0bcf7b5311c0d59ec26c51 Mon Sep 17 00:00:00 2001 From: Marc Mascort Bou Date: Mon, 16 Jul 2018 19:14:30 +0200 Subject: [PATCH 01/72] Ignore Netbeans config directory --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3b99cf4..2e1fc0e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ composer.lock docs vendor coverage -.idea \ No newline at end of file +.idea +nbproject \ No newline at end of file From 4e7ae8accb57d77d3302a29f7a2687ad1fed1ff6 Mon Sep 17 00:00:00 2001 From: Marc Mascort Bou Date: Mon, 16 Jul 2018 19:23:55 +0200 Subject: [PATCH 02/72] Lumen Service Provider --- src/LumenQueryDetectorServiceProvider.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/LumenQueryDetectorServiceProvider.php diff --git a/src/LumenQueryDetectorServiceProvider.php b/src/LumenQueryDetectorServiceProvider.php new file mode 100644 index 0000000..c73202e --- /dev/null +++ b/src/LumenQueryDetectorServiceProvider.php @@ -0,0 +1,21 @@ +app->configure('querydetector'); + $this->mergeConfigFrom(__DIR__ . '/../config/config.php', 'querydetector'); + + $this->app->middleware([ + QueryDetectorMiddleware::class + ]); + + $this->app->singleton(QueryDetector::class); + $this->app->alias(QueryDetector::class, 'querydetector'); + } +} From 26d08837ac773065abab665164878c75795f8344 Mon Sep 17 00:00:00 2001 From: Marc Mascort Bou Date: Mon, 16 Jul 2018 19:24:20 +0200 Subject: [PATCH 03/72] Add Lumen usage in README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 8c3629f..1358c29 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,12 @@ return [ ]; ``` +If you use **Lumen**, you need to copy the config file manually and register the Lumen Service Provider in `bootstrap/app.php` file + +```php +$this->app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class); +``` + ### Testing ``` bash From c0a305fa712c4461d35c6c5e9d9a4ae770b45971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cem=20Y=C4=B1lmaz?= Date: Wed, 18 Jul 2018 02:01:51 +0300 Subject: [PATCH 04/72] Create Console.php Added console.warn method to see outputs in the developer tool console --- src/Outputs/Console.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/Outputs/Console.php diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php new file mode 100644 index 0000000..267e292 --- /dev/null +++ b/src/Outputs/Console.php @@ -0,0 +1,37 @@ +isRedirection()) { + return; + } + $content = $response->getContent(); + $outputContent = $this->getOutputContent($detectedQueries); + $pos = strripos($content, ''); + if (false !== $pos) { + $content = substr($content, 0, $pos) . $outputContent . substr($content, $pos); + } else { + $content = $content . $outputContent; + } + // Update the new content and reset the content length + $response->setContent($content); + $response->headers->remove('Content-Length'); + } + protected function getOutputContent(Collection $detectedQueries) + { + $output = ''; + return $output; + } +} From 1e9fe289f49e5e6d50a63befdc191d6139b6ae34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cem=20Y=C4=B1lmaz?= Date: Wed, 18 Jul 2018 02:02:26 +0300 Subject: [PATCH 05/72] Update Console.php forgot to change class name :| --- src/Outputs/Console.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php index 267e292..a2a54b7 100644 --- a/src/Outputs/Console.php +++ b/src/Outputs/Console.php @@ -2,7 +2,7 @@ namespace BeyondCode\QueryDetector\Outputs; use Illuminate\Support\Collection; use Symfony\Component\HttpFoundation\Response; -class Alert implements Output +class Console implements Output { public function output(Collection $detectedQueries, Response $response) { From fd3ac6e366bbd5152887d15c30b12ec933b2b014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cem=20Y=C4=B1lmaz?= Date: Wed, 18 Jul 2018 02:08:46 +0300 Subject: [PATCH 06/72] Fixed whitespace --- src/Outputs/Console.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php index a2a54b7..00af6bb 100644 --- a/src/Outputs/Console.php +++ b/src/Outputs/Console.php @@ -2,6 +2,7 @@ namespace BeyondCode\QueryDetector\Outputs; use Illuminate\Support\Collection; use Symfony\Component\HttpFoundation\Response; + class Console implements Output { public function output(Collection $detectedQueries, Response $response) From 36339264c769aa85fa8fa5a520f83a94fe1d657e Mon Sep 17 00:00:00 2001 From: Adrian Crisan Date: Wed, 18 Jul 2018 14:54:47 +0300 Subject: [PATCH 07/72] Debugbar output --- config/config.php | 4 ++++ src/Outputs/Debugbar.php | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/Outputs/Debugbar.php diff --git a/config/config.php b/config/config.php index cd4e50d..75dc268 100644 --- a/config/config.php +++ b/config/config.php @@ -29,6 +29,10 @@ * Displays an alert on the website * \BeyondCode\QueryDetector\Outputs\Alert::class * + * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) + * Writes the N+1 queries into a custom messages collector of Debugbar + * \BeyondCode\QueryDetector\Outputs\Debugbar::class + * * Log: * Writes the N+1 queries into the Laravel.log file * \BeyondCode\QueryDetector\Outputs\Log::class diff --git a/src/Outputs/Debugbar.php b/src/Outputs/Debugbar.php new file mode 100644 index 0000000..fa297b7 --- /dev/null +++ b/src/Outputs/Debugbar.php @@ -0,0 +1,27 @@ +addMessage(sprintf('Model: %s => Relation: %s - You should add with(%s) to eager-load this relation.', + $detectedQuery['model'], + $detectedQuery['relation'], + $detectedQuery['relation'] + )); + } + + LaravelDebugbar::addCollector($collector); + } +} From 308eba2b08f8abd7e2dc6e24f28a26413b471baf Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 18 Jul 2018 16:13:09 +0200 Subject: [PATCH 08/72] Check for object key existence --- src/QueryDetector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QueryDetector.php b/src/QueryDetector.php index 001f986..59621b4 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -55,7 +55,7 @@ public function logQuery($query, Collection $backtrace) }); // We try to access a relation - if (is_array($relation)) { + if (is_array($relation) && isset($relation['object'])) { if ($relation['class'] === Relation::class) { $model = get_class($relation['object']->getParent()); $relationName = get_class($relation['object']->getRelated()); From 088510a09383e2e08d90ef590c4281e492d8552d Mon Sep 17 00:00:00 2001 From: Robert Rimoczi Date: Wed, 18 Jul 2018 16:45:06 +0200 Subject: [PATCH 09/72] fire event when unoptimized queries are found --- src/Events/QueryDetected.php | 26 ++++++++++++++++++++++++ src/QueryDetector.php | 9 ++++++++- tests/QueryDetectorTest.php | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/Events/QueryDetected.php diff --git a/src/Events/QueryDetected.php b/src/Events/QueryDetected.php new file mode 100644 index 0000000..635ac4f --- /dev/null +++ b/src/Events/QueryDetected.php @@ -0,0 +1,26 @@ +queries = $queries; + } + + /** + * @return Collection + */ + public function getQueries() + { + return $this->queries; + } +} diff --git a/src/QueryDetector.php b/src/QueryDetector.php index ada50e8..3db2a80 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Builder; use Symfony\Component\HttpFoundation\Response; use Illuminate\Database\Eloquent\Relations\Relation; +use BeyondCode\QueryDetector\Events\QueryDetected; class QueryDetector { @@ -167,7 +168,13 @@ public function getDetectedQueries(): Collection } } - return $queries->where('count', '>', config('querydetector.threshold', 1))->values(); + $queries = $queries->where('count', '>', config('querydetector.threshold', 1))->values(); + + if ($queries->isNotEmpty()) { + event(new QueryDetected($queries)); + } + + return $queries; } protected function applyOutput(Response $response) diff --git a/tests/QueryDetectorTest.php b/tests/QueryDetectorTest.php index 48405e0..c0b144b 100644 --- a/tests/QueryDetectorTest.php +++ b/tests/QueryDetectorTest.php @@ -3,7 +3,9 @@ namespace BeyondCode\QueryDetector\Tests; use Route; +use Illuminate\Support\Facades\Event; use BeyondCode\QueryDetector\QueryDetector; +use BeyondCode\QueryDetector\Events\QueryDetected; use BeyondCode\QueryDetector\Tests\Models\Post; use BeyondCode\QueryDetector\Tests\Models\Author; use BeyondCode\QueryDetector\Tests\Models\Comment; @@ -224,4 +226,40 @@ public function it_ignores_redirects() $this->assertCount(1, $queries); } + + /** @test */ + public function it_fires_an_event_if_detects_n1_query() + { + Event::fake(); + + Route::get('/', function (){ + $authors = Author::all(); + + foreach ($authors as $author) { + $author->profile; + } + }); + + $this->get('/'); + + Event::assertDispatched(QueryDetected::class); + } + + /** @test */ + public function it_does_not_fire_an_event_if_there_is_no_n1_query() + { + Event::fake(); + + Route::get('/', function (){ + $authors = Author::with('profile')->get(); + + foreach ($authors as $author) { + $author->profile; + } + }); + + $this->get('/'); + + Event::assertNotDispatched(QueryDetected::class); + } } From 62f8f33c69fc25c470618266e83c50956050889b Mon Sep 17 00:00:00 2001 From: Robert Rimoczi Date: Wed, 18 Jul 2018 16:58:53 +0200 Subject: [PATCH 10/72] update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 714e991..50d77c4 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,8 @@ If you use **Lumen**, you need to copy the config file manually and register the $this->app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class); ``` +If you need additional logic to run when the package detects unoptimized queries, you can listen to the `\BeyondCode\QueryDetector\Events\QueryDetected` event and write a listener to run your own handler. (e.g. send warning to Sentry/Bugsnag, send Slack notification, etc.) + ### Testing ``` bash From a369f78891c905ec94b17193dbcef1dd926af7c6 Mon Sep 17 00:00:00 2001 From: Jack W-H Date: Wed, 18 Jul 2018 16:28:57 +0100 Subject: [PATCH 11/72] Fixed a bug that could cause illegal type offsets See https://github.com/beyondcode/laravel-query-detector/issues/14 --- src/QueryDetector.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/QueryDetector.php b/src/QueryDetector.php index ada50e8..52d831a 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -172,14 +172,14 @@ public function getDetectedQueries(): Collection protected function applyOutput(Response $response) { - $outputTypes = app(config('querydetector.output')); + $outputTypes = config('querydetector.output'); if (! is_array($outputTypes)) { - $types = [$outputTypes]; + $outputTypes = [$outputTypes]; } foreach ($outputTypes as $type) { - $type->output($this->getDetectedQueries(), $response); + app($type)->output($this->getDetectedQueries(), $response); } } From 335f7dd5dd41b8c5c2769eb7c40a0480117d3626 Mon Sep 17 00:00:00 2001 From: Jan Piotrowski Date: Wed, 18 Jul 2018 18:48:13 +0200 Subject: [PATCH 12/72] Fix output of relationship name in advice part of alert Namespace \ was getting eaten. fixes part of #9 --- src/Outputs/Alert.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Outputs/Alert.php b/src/Outputs/Alert.php index e951d74..4171a33 100644 --- a/src/Outputs/Alert.php +++ b/src/Outputs/Alert.php @@ -37,7 +37,7 @@ protected function getOutputContent(Collection $detectedQueries) $output .= "alert('Found the following N+1 queries in this request:\\n\\n"; foreach ($detectedQueries as $detectedQuery) { $output .= "Model: ".addslashes($detectedQuery['model']). " => Relation: ".addslashes($detectedQuery['relation']); - $output .= " - You should add \"with(\'".$detectedQuery['relation']."\')\" to eager-load this relation."; + $output .= " - You should add \"with(\'".addslashes($detectedQuery['relation'])."\')\" to eager-load this relation."; $output .= "\\n"; } $output .= "')"; @@ -45,4 +45,4 @@ protected function getOutputContent(Collection $detectedQueries) return $output; } -} \ No newline at end of file +} From 4901f8e545061308c88e9c5103d11d22c0353504 Mon Sep 17 00:00:00 2001 From: Jan Piotrowski Date: Wed, 18 Jul 2018 18:53:46 +0200 Subject: [PATCH 13/72] Add more alternative outputs to README added console logging and debugbar to description, and debugbar to code example --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 50d77c4..06c10ef 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,9 @@ The package will automatically register itself. If you run your application in the `debug` mode, the query monitor will be automatically active. So there is nothing you have to do. -By default, this package will display an `alert()` message to notify you about an N+1 query found in the current request. If you rather want this information to be written to your `laravel.log` file, you can publish the configuration and change the output behaviour (see example below). +By default, this package will display an `alert()` message to notify you about an N+1 query found in the current request. + +If you rather want this information to be written to your `laravel.log` file, written to your browser's console log as a warning or listed in a new tab for the [Laravel Debugbar (barryvdh/laravel-debugbar)](https://github.com/barryvdh/laravel-debugbar), you can publish the configuration and change the output behaviour (see example below). You can publish the package's configuration using this command: @@ -71,6 +73,10 @@ return [ * Displays an alert on the website * \BeyondCode\QueryDetector\Outputs\Alert::class * + * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) + * Writes the N+1 queries into a custom messages collector of Debugbar + * \BeyondCode\QueryDetector\Outputs\Debugbar::class + * * Log: * Writes the N+1 queries into the Laravel.log file * \BeyondCode\QueryDetector\Outputs\Log::class From bc1d061243f382e8cea99281f65c6ff9e4d1d44e Mon Sep 17 00:00:00 2001 From: Jan Piotrowski Date: Wed, 18 Jul 2018 18:57:32 +0200 Subject: [PATCH 14/72] Debugbar: Add backticks to clearly indicate code --- src/Outputs/Debugbar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Outputs/Debugbar.php b/src/Outputs/Debugbar.php index fa297b7..7f183ed 100644 --- a/src/Outputs/Debugbar.php +++ b/src/Outputs/Debugbar.php @@ -15,7 +15,7 @@ public function output(Collection $detectedQueries, Response $response) $collector = new MessagesCollector('N+1 Queries'); foreach ($detectedQueries as $detectedQuery) { - $collector->addMessage(sprintf('Model: %s => Relation: %s - You should add with(%s) to eager-load this relation.', + $collector->addMessage(sprintf('Model: %s => Relation: %s - You should add `with(%s)` to eager-load this relation.', $detectedQuery['model'], $detectedQuery['relation'], $detectedQuery['relation'] From c9ef1f525ac90f4f11a9be69e2a890705aee83ca Mon Sep 17 00:00:00 2001 From: Rob Burley Date: Thu, 19 Jul 2018 11:38:18 +0100 Subject: [PATCH 15/72] add console.log option to config comment and readme --- README.md | 4 ++++ config/config.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 06c10ef..c409c03 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,10 @@ return [ * Log: * Writes the N+1 queries into the Laravel.log file * \BeyondCode\QueryDetector\Outputs\Log::class + * + * Console: + * Writes the N+1 queries into your browsers console log + * \BeyondCode\QueryDetector\Outputs\Console::class */ 'output' => [ \BeyondCode\QueryDetector\Outputs\Alert::class diff --git a/config/config.php b/config/config.php index 75dc268..392877c 100644 --- a/config/config.php +++ b/config/config.php @@ -36,6 +36,10 @@ * Log: * Writes the N+1 queries into the Laravel.log file * \BeyondCode\QueryDetector\Outputs\Log::class + * + * Console: + * Writes the N+1 queries into your browsers console log + * \BeyondCode\QueryDetector\Outputs\Console::class */ 'output' => [ \BeyondCode\QueryDetector\Outputs\Log::class, From be3f050350f585730f33285da0bde3199bbf46b3 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Thu, 19 Jul 2018 22:36:14 +0200 Subject: [PATCH 16/72] Use latest stacktrace frame to find unique queries --- src/QueryDetector.php | 8 +++++--- tests/QueryDetectorTest.php | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/QueryDetector.php b/src/QueryDetector.php index bb4afba..11d3494 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -67,7 +67,9 @@ public function logQuery($query, Collection $backtrace) $relatedModel = $relationName; } - $key = md5($query->sql . $model . $relationName); + $sources = $this->findSource($backtrace); + + $key = md5($query->sql . $model . $relationName . $sources[0]->name . $sources[0]->line); $count = array_get($this->queries, $key.'.count', 0); @@ -77,7 +79,7 @@ public function logQuery($query, Collection $backtrace) 'model' => $model, 'relatedModel' => $relatedModel, 'relation' => $relationName, - 'sources' => $this->findSource($backtrace) + 'sources' => $sources ]; } } @@ -91,7 +93,7 @@ protected function findSource($stack) $sources[] = $this->parseTrace($index, $trace); } - return array_filter($sources); + return array_values(array_filter($sources)); } public function parseTrace($index, array $trace) diff --git a/tests/QueryDetectorTest.php b/tests/QueryDetectorTest.php index c0b144b..b428e2a 100644 --- a/tests/QueryDetectorTest.php +++ b/tests/QueryDetectorTest.php @@ -262,4 +262,30 @@ public function it_does_not_fire_an_event_if_there_is_no_n1_query() Event::assertNotDispatched(QueryDetected::class); } + /** @test */ + public function it_uses_the_trace_line_to_detect_queries() + { + Route::get('/', function (){ + $authors = Author::all(); + $authors2 = Author::all(); + + foreach ($authors as $author) { + $author->profile->city; + } + + foreach ($authors2 as $author) { + $author->profile->city; + } + }); + + $this->get('/'); + + $queries = app(QueryDetector::class)->getDetectedQueries(); + + $this->assertCount(2, $queries); + + $this->assertSame(Author::count(), $queries[0]['count']); + $this->assertSame(Author::class, $queries[0]['model']); + $this->assertSame('profile', $queries[0]['relation']); + } } From a06a15d93a4feb38935ab5410b10574ff4f10f5b Mon Sep 17 00:00:00 2001 From: Marc Mascort Bou Date: Fri, 20 Jul 2018 13:09:59 +0200 Subject: [PATCH 17/72] Json Output --- src/Outputs/Json.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Outputs/Json.php diff --git a/src/Outputs/Json.php b/src/Outputs/Json.php new file mode 100644 index 0000000..71dc695 --- /dev/null +++ b/src/Outputs/Json.php @@ -0,0 +1,19 @@ +getData(true); + $data['warning_queries'] = $detectedQueries; + $response->setData($data); + } + } +} From 2306de83c6d21ef4eedfa385a208d295be43b301 Mon Sep 17 00:00:00 2001 From: Marc Mascort Bou Date: Fri, 20 Jul 2018 13:11:06 +0200 Subject: [PATCH 18/72] Fix lumen example on readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c409c03..aee4773 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ return [ If you use **Lumen**, you need to copy the config file manually and register the Lumen Service Provider in `bootstrap/app.php` file ```php -$this->app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class); +$app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class); ``` If you need additional logic to run when the package detects unoptimized queries, you can listen to the `\BeyondCode\QueryDetector\Events\QueryDetected` event and write a listener to run your own handler. (e.g. send warning to Sentry/Bugsnag, send Slack notification, etc.) From 423867f192b479ed01adf53ca3ea895c424758d0 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Fri, 20 Jul 2018 14:39:09 +0200 Subject: [PATCH 19/72] Update config.php --- config/config.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/config.php b/config/config.php index 392877c..06de878 100644 --- a/config/config.php +++ b/config/config.php @@ -40,6 +40,10 @@ * Console: * Writes the N+1 queries into your browsers console log * \BeyondCode\QueryDetector\Outputs\Console::class + * + * JSON: + * Writes the N+1 queries into the response body of your JSON responses + * \BeyondCode\QueryDetector\Outputs\Json::class */ 'output' => [ \BeyondCode\QueryDetector\Outputs\Log::class, From d790bcf2ac6b9739404e63214b23ae2cc55db56d Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Fri, 20 Jul 2018 14:39:23 +0200 Subject: [PATCH 20/72] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index aee4773..b6d78a7 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,10 @@ return [ * Console: * Writes the N+1 queries into your browsers console log * \BeyondCode\QueryDetector\Outputs\Console::class + * + * JSON: + * Writes the N+1 queries into the response body of your JSON responses + * \BeyondCode\QueryDetector\Outputs\Json::class */ 'output' => [ \BeyondCode\QueryDetector\Outputs\Alert::class From 4753017ee5368f74da38363eebd93bbbd2c06f4f Mon Sep 17 00:00:00 2001 From: Erik Verbeek Date: Fri, 20 Jul 2018 16:29:55 +0200 Subject: [PATCH 21/72] Expanded the console log warning to have the same level of details as the laravel.log --- src/Outputs/Console.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php index 00af6bb..bd20f1a 100644 --- a/src/Outputs/Console.php +++ b/src/Outputs/Console.php @@ -27,9 +27,18 @@ protected function getOutputContent(Collection $detectedQueries) $output = ''; From aeb4a48c1baaf0d7d17d0c73bf1ebfd65800ac6c Mon Sep 17 00:00:00 2001 From: Erik Verbeek Date: Fri, 20 Jul 2018 16:34:22 +0200 Subject: [PATCH 22/72] Removed spaces to have the same coding style as the plugin --- src/Outputs/Alert.php | 2 +- src/Outputs/Console.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Outputs/Alert.php b/src/Outputs/Alert.php index 4171a33..61257e9 100644 --- a/src/Outputs/Alert.php +++ b/src/Outputs/Alert.php @@ -36,7 +36,7 @@ protected function getOutputContent(Collection $detectedQueries) $output = ''; + return $output; } } From c4ce25ae8efe9896e63f91f4be6a82aaf33636ba Mon Sep 17 00:00:00 2001 From: Steve Lacey Date: Sat, 21 Jul 2018 11:48:07 +0200 Subject: [PATCH 24/72] Assert response is html before injecting alert or console outputs --- src/Outputs/Alert.php | 2 +- src/Outputs/Console.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Outputs/Alert.php b/src/Outputs/Alert.php index 4171a33..ae7db97 100644 --- a/src/Outputs/Alert.php +++ b/src/Outputs/Alert.php @@ -9,7 +9,7 @@ class Alert implements Output { public function output(Collection $detectedQueries, Response $response) { - if ($response->isRedirection()) { + if (stripos($response->headers->get('Content-Type'), 'text/html') !== 0 || $response->isRedirection()) { return; } diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php index 48800db..6919952 100644 --- a/src/Outputs/Console.php +++ b/src/Outputs/Console.php @@ -9,7 +9,7 @@ class Console implements Output { public function output(Collection $detectedQueries, Response $response) { - if ($response->isRedirection()) { + if (stripos($response->headers->get('Content-Type'), 'text/html') !== 0 || $response->isRedirection()) { return; } From e146f0e3bb5818d7a5366ac6ae0d8dfaa82b80f5 Mon Sep 17 00:00:00 2001 From: Matt Isenhower Date: Wed, 25 Jul 2018 11:08:54 -0700 Subject: [PATCH 25/72] Fix issues with Debugbar output when used with SPAs/ajax requests Debugbar's UI only shows tabs for MessageCollectors added during the initial page load. Previously, the N+1 Queries MessageCollector was only added to Debugbar when N+1 queries were actually detected. This meant that if no queries were detected on the initial page load, but they were detected during subsequent requests made via JS, those queries wouldn't show up because the tab wouldn't appear within Debugbar. --- src/Outputs/Alert.php | 5 +++++ src/Outputs/Console.php | 5 +++++ src/Outputs/Debugbar.php | 15 ++++++++++----- src/Outputs/Json.php | 4 ++++ src/Outputs/Log.php | 7 ++++++- src/Outputs/Output.php | 4 +++- src/QueryDetector.php | 14 ++++++++++++-- 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/Outputs/Alert.php b/src/Outputs/Alert.php index ae7db97..4a59b93 100644 --- a/src/Outputs/Alert.php +++ b/src/Outputs/Alert.php @@ -7,6 +7,11 @@ class Alert implements Output { + public function boot() + { + // + } + public function output(Collection $detectedQueries, Response $response) { if (stripos($response->headers->get('Content-Type'), 'text/html') !== 0 || $response->isRedirection()) { diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php index 6919952..245b85f 100644 --- a/src/Outputs/Console.php +++ b/src/Outputs/Console.php @@ -7,6 +7,11 @@ class Console implements Output { + public function boot() + { + // + } + public function output(Collection $detectedQueries, Response $response) { if (stripos($response->headers->get('Content-Type'), 'text/html') !== 0 || $response->isRedirection()) { diff --git a/src/Outputs/Debugbar.php b/src/Outputs/Debugbar.php index 7f183ed..31ff9c0 100644 --- a/src/Outputs/Debugbar.php +++ b/src/Outputs/Debugbar.php @@ -10,18 +10,23 @@ class Debugbar implements Output { - public function output(Collection $detectedQueries, Response $response) + protected $collector; + + public function boot() { - $collector = new MessagesCollector('N+1 Queries'); + $this->collector = new MessagesCollector('N+1 Queries'); + + LaravelDebugbar::addCollector($this->collector); + } + public function output(Collection $detectedQueries, Response $response) + { foreach ($detectedQueries as $detectedQuery) { - $collector->addMessage(sprintf('Model: %s => Relation: %s - You should add `with(%s)` to eager-load this relation.', + $this->collector->addMessage(sprintf('Model: %s => Relation: %s - You should add `with(%s)` to eager-load this relation.', $detectedQuery['model'], $detectedQuery['relation'], $detectedQuery['relation'] )); } - - LaravelDebugbar::addCollector($collector); } } diff --git a/src/Outputs/Json.php b/src/Outputs/Json.php index 71dc695..21b387e 100644 --- a/src/Outputs/Json.php +++ b/src/Outputs/Json.php @@ -7,6 +7,10 @@ class Json implements Output { + public function boot() + { + // + } public function output(Collection $detectedQueries, Response $response) { diff --git a/src/Outputs/Log.php b/src/Outputs/Log.php index b8a386d..2c9349f 100644 --- a/src/Outputs/Log.php +++ b/src/Outputs/Log.php @@ -8,6 +8,11 @@ class Log implements Output { + public function boot() + { + // + } + public function output(Collection $detectedQueries, Response $response) { LaravelLog::info('Detected N+1 Query'); @@ -23,4 +28,4 @@ public function output(Collection $detectedQueries, Response $response) } } } -} \ No newline at end of file +} diff --git a/src/Outputs/Output.php b/src/Outputs/Output.php index accb26c..0dbe531 100644 --- a/src/Outputs/Output.php +++ b/src/Outputs/Output.php @@ -7,5 +7,7 @@ interface Output { + public function boot(); + public function output(Collection $detectedQueries, Response $response); -} \ No newline at end of file +} diff --git a/src/QueryDetector.php b/src/QueryDetector.php index 11d3494..c9b316f 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -26,6 +26,11 @@ public function boot() $this->logQuery($query, $backtrace); }); + + foreach ($this->getOutputTypes() as $outputType) { + app()->singleton($outputType); + app($outputType)->boot(); + } } public function isEnabled(): bool @@ -179,7 +184,7 @@ public function getDetectedQueries(): Collection return $queries; } - protected function applyOutput(Response $response) + protected function getOutputTypes() { $outputTypes = config('querydetector.output'); @@ -187,7 +192,12 @@ protected function applyOutput(Response $response) $outputTypes = [$outputTypes]; } - foreach ($outputTypes as $type) { + return $outputTypes; + } + + protected function applyOutput(Response $response) + { + foreach ($this->getOutputTypes() as $type) { app($type)->output($this->getDetectedQueries(), $response); } } From cbf5174a79c4b1da875ffc599c46d1dc7f850fac Mon Sep 17 00:00:00 2001 From: Stanislav Plakhin Date: Mon, 30 Jul 2018 00:00:33 +0600 Subject: [PATCH 26/72] Add Clockwork output Simply adds warnings to Clockwork Log if N+1 queries detected --- src/Outputs/Clockwork.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Outputs/Clockwork.php diff --git a/src/Outputs/Clockwork.php b/src/Outputs/Clockwork.php new file mode 100644 index 0000000..533bcbd --- /dev/null +++ b/src/Outputs/Clockwork.php @@ -0,0 +1,14 @@ +warning("{$detectedQueries->count()} N+1 queries detected:", $detectedQueries->toArray()); + } +} From 4463719dd0a38521e07b9b949676fac707ace892 Mon Sep 17 00:00:00 2001 From: Stanislav Plakhin Date: Mon, 30 Jul 2018 00:08:16 +0600 Subject: [PATCH 27/72] add Clockwork option to config --- config/config.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/config/config.php b/config/config.php index 06de878..825d04a 100644 --- a/config/config.php +++ b/config/config.php @@ -29,21 +29,25 @@ * Displays an alert on the website * \BeyondCode\QueryDetector\Outputs\Alert::class * - * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) - * Writes the N+1 queries into a custom messages collector of Debugbar - * \BeyondCode\QueryDetector\Outputs\Debugbar::class - * - * Log: - * Writes the N+1 queries into the Laravel.log file - * \BeyondCode\QueryDetector\Outputs\Log::class - * * Console: * Writes the N+1 queries into your browsers console log * \BeyondCode\QueryDetector\Outputs\Console::class * + * Clockwork: (make sure you have the itsgoingd/clockwork package installed) + * Writes the N+1 queries warnings to Clockwork log + * \BeyondCode\QueryDetector\Outputs\Clockwork::class + * + * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) + * Writes the N+1 queries into a custom messages collector of Debugbar + * \BeyondCode\QueryDetector\Outputs\Debugbar::class + * * JSON: * Writes the N+1 queries into the response body of your JSON responses * \BeyondCode\QueryDetector\Outputs\Json::class + * + * Log: + * Writes the N+1 queries into the Laravel.log file + * \BeyondCode\QueryDetector\Outputs\Log::class */ 'output' => [ \BeyondCode\QueryDetector\Outputs\Log::class, From 3c860ab7c841bc8bff41c0b66badc05af6fd1c02 Mon Sep 17 00:00:00 2001 From: Stanislav Plakhin Date: Mon, 30 Jul 2018 00:11:45 +0600 Subject: [PATCH 28/72] Update README.md Updates README in accordance with updated config --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b6d78a7..1392bc8 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,8 @@ return [ * \BeyondCode\QueryDetector\Outputs\Json::class */ 'output' => [ - \BeyondCode\QueryDetector\Outputs\Alert::class + \BeyondCode\QueryDetector\Outputs\Log::class, + \BeyondCode\QueryDetector\Outputs\Alert::class, ] ]; From 016cc1b7672a7cb1ef92239bb761fc0f1adeffb8 Mon Sep 17 00:00:00 2001 From: Stanislav Plakhin Date: Mon, 30 Jul 2018 00:16:46 +0600 Subject: [PATCH 29/72] Update README.md Updates README in accordance with updated config --- README.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1392bc8..5f2cd06 100644 --- a/README.md +++ b/README.md @@ -66,28 +66,32 @@ return [ ], /* - * Define the output format that you want to use. Multiple classes are supported + * Define the output formats that you want to use. * Available options are: * * Alert: * Displays an alert on the website * \BeyondCode\QueryDetector\Outputs\Alert::class * - * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) - * Writes the N+1 queries into a custom messages collector of Debugbar - * \BeyondCode\QueryDetector\Outputs\Debugbar::class - * - * Log: - * Writes the N+1 queries into the Laravel.log file - * \BeyondCode\QueryDetector\Outputs\Log::class - * * Console: * Writes the N+1 queries into your browsers console log * \BeyondCode\QueryDetector\Outputs\Console::class * + * Clockwork: (make sure you have the itsgoingd/clockwork package installed) + * Writes the N+1 queries warnings to Clockwork log + * \BeyondCode\QueryDetector\Outputs\Clockwork::class + * + * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) + * Writes the N+1 queries into a custom messages collector of Debugbar + * \BeyondCode\QueryDetector\Outputs\Debugbar::class + * * JSON: * Writes the N+1 queries into the response body of your JSON responses * \BeyondCode\QueryDetector\Outputs\Json::class + * + * Log: + * Writes the N+1 queries into the Laravel.log file + * \BeyondCode\QueryDetector\Outputs\Log::class */ 'output' => [ \BeyondCode\QueryDetector\Outputs\Log::class, From b7b75434a971bc105a9316f45343058cd2f5e22f Mon Sep 17 00:00:00 2001 From: Stanislav Plakhin Date: Mon, 30 Jul 2018 00:23:26 +0600 Subject: [PATCH 30/72] Update config.php --- config/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.php b/config/config.php index 825d04a..b7c63cf 100644 --- a/config/config.php +++ b/config/config.php @@ -22,7 +22,7 @@ ], /* - * Define the output formats that you want to use. + * Define the output format that you want to use. Multiple classes are supported. * Available options are: * * Alert: @@ -50,7 +50,7 @@ * \BeyondCode\QueryDetector\Outputs\Log::class */ 'output' => [ - \BeyondCode\QueryDetector\Outputs\Log::class, \BeyondCode\QueryDetector\Outputs\Alert::class, + \BeyondCode\QueryDetector\Outputs\Log::class, ] ]; From 591ad6075412c13292a3f132946983b978a7105e Mon Sep 17 00:00:00 2001 From: Stanislav Plakhin Date: Mon, 30 Jul 2018 00:23:57 +0600 Subject: [PATCH 31/72] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f2cd06..f80cab1 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ return [ ], /* - * Define the output formats that you want to use. + * Define the output format that you want to use. Multiple classes are supported. * Available options are: * * Alert: From 3433a74022939d329726a489778e65183e3d7a75 Mon Sep 17 00:00:00 2001 From: Yu Li Date: Wed, 15 Aug 2018 12:30:18 +0800 Subject: [PATCH 32/72] Clockwork Output error fix #33 --- src/Outputs/Clockwork.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Outputs/Clockwork.php b/src/Outputs/Clockwork.php index 533bcbd..fea7055 100644 --- a/src/Outputs/Clockwork.php +++ b/src/Outputs/Clockwork.php @@ -7,6 +7,11 @@ class Clockwork implements Output { + public function boot() + { + // + } + public function output(Collection $detectedQueries, Response $response) { clock()->warning("{$detectedQueries->count()} N+1 queries detected:", $detectedQueries->toArray()); From 5095819b6d8e21c1668818190548d39a5ce385cd Mon Sep 17 00:00:00 2001 From: Bader Almutairi Date: Sat, 18 Aug 2018 11:54:47 +0300 Subject: [PATCH 33/72] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 116389e..05b04ba 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^7.1", - "illuminate/support": "5.5.*|5.6.*" + "illuminate/support": "5.5.*|5.6.*|5.7.*" }, "require-dev": { "orchestra/testbench": "3.6.*", From 3fa1c580064a9dd66c561a6911f67d7c7254bba7 Mon Sep 17 00:00:00 2001 From: Anders Fajersson Date: Fri, 30 Nov 2018 14:34:46 +0100 Subject: [PATCH 34/72] Add time to logged query --- src/QueryDetector.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/QueryDetector.php b/src/QueryDetector.php index c9b316f..0e24f99 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -77,9 +77,11 @@ public function logQuery($query, Collection $backtrace) $key = md5($query->sql . $model . $relationName . $sources[0]->name . $sources[0]->line); $count = array_get($this->queries, $key.'.count', 0); + $time = array_get($this->queries, $key.'.time', 0); $this->queries[$key] = [ 'count' => ++$count, + 'time' => $time + $query->time, 'query' => $query->sql, 'model' => $model, 'relatedModel' => $relatedModel, From 420053d3fc5fb06867ebc6cd362a9bc689e178cb Mon Sep 17 00:00:00 2001 From: arubacao Date: Fri, 7 Dec 2018 10:57:09 +0100 Subject: [PATCH 35/72] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4084157..24c2d6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: php php: - 7.1 - 7.2 + - 7.3 env: matrix: From 97a61e6864e7ddb9ba592dba78e7f55c1e927165 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Thu, 13 Dec 2018 21:42:53 +0100 Subject: [PATCH 36/72] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f80cab1..853be13 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ If you rather want this information to be written to your `laravel.log` file, wr You can publish the package's configuration using this command: ```bash -php artisan vendor:publish --provider=BeyondCode\\QueryDetector\\QueryDetectorServiceProvider +php artisan vendor:publish --provider=BeyondCode\QueryDetector\QueryDetectorServiceProvider ``` This will add the `querydetector.php` file in your config directory with the following contents: From f9c2595c105e9b03774981b574e43add03102f36 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Thu, 13 Dec 2018 21:47:27 +0100 Subject: [PATCH 37/72] do not log callstack in single steps --- src/Outputs/Log.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Outputs/Log.php b/src/Outputs/Log.php index 2c9349f..9aa2c18 100644 --- a/src/Outputs/Log.php +++ b/src/Outputs/Log.php @@ -16,16 +16,21 @@ public function boot() public function output(Collection $detectedQueries, Response $response) { LaravelLog::info('Detected N+1 Query'); + foreach ($detectedQueries as $detectedQuery) { - LaravelLog::info('Model: '.$detectedQuery['model']); - LaravelLog::info('Relation: '.$detectedQuery['relation']); - LaravelLog::info('Num-Called: '.$detectedQuery['count']); + $logOutput = 'Model: '.$detectedQuery['model'] . PHP_EOL; + + $logOutput .= 'Relation: '.$detectedQuery['relation'] . PHP_EOL; - LaravelLog::info('Call-Stack:'); + $logOutput .= 'Num-Called: '.$detectedQuery['count'] . PHP_EOL; + + $logOutput .= 'Call-Stack:' . PHP_EOL; foreach ($detectedQuery['sources'] as $source) { - LaravelLog::info('#'.$source->index.' '.$source->name.':'.$source->line); + $logOutput .= '#'.$source->index.' '.$source->name.':'.$source->line . PHP_EOL; } + + LaravelLog::info($logOutput); } } } From 2470de036eeccd36463ddaf55ebf52098bcb2ed6 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Thu, 13 Dec 2018 21:56:26 +0100 Subject: [PATCH 38/72] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 853be13..880e79a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,9 @@ The Laravel N+1 query detector helps you to increase your application's performa ![Example alert](https://beyondco.de/github/n+1/alert.png) +> If you want to learn how to create reusable PHP packages yourself, take a look at my upcoming [PHP Package Development](https://phppackagedevelopment.com) video course. + + ## Installation You can install the package via composer: From 3551306ce1e31add7a650ef842394ec9831f83fd Mon Sep 17 00:00:00 2001 From: Kris Kelly Date: Tue, 26 Feb 2019 23:03:30 +0000 Subject: [PATCH 39/72] Added support for illuminate/support 5.8 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 05b04ba..6960203 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^7.1", - "illuminate/support": "5.5.*|5.6.*|5.7.*" + "illuminate/support": "5.5.*|5.6.*|5.7.*|5.8.*" }, "require-dev": { "orchestra/testbench": "3.6.*", From 14c8138abbb6921e16cf3ab5b033aa76a6305c4c Mon Sep 17 00:00:00 2001 From: feek <5747667+mr-feek@users.noreply.github.com> Date: Mon, 11 Mar 2019 12:08:31 -0700 Subject: [PATCH 40/72] add threshold to config file This is listed in the readme, but not in the actual published config --- config/config.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/config.php b/config/config.php index b7c63cf..aa058d8 100644 --- a/config/config.php +++ b/config/config.php @@ -6,6 +6,12 @@ * If this is set to "null", the app.debug config value will be used. */ 'enabled' => env('QUERY_DETECTOR_ENABLED', null), + + /* + * Threshold level for the N+1 query detection. If a relation query will be + * executed more then this amount, the detector will notify you about it. + */ + 'threshold' => 1, /* * Here you can whitelist model relations. From 63dd0a6a3c469d2040a546fd6140aff9373a3ab5 Mon Sep 17 00:00:00 2001 From: feek <5747667+mr-feek@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:35:43 -0700 Subject: [PATCH 41/72] fix: dont add the collector to debugbar twice --- src/Outputs/Debugbar.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Outputs/Debugbar.php b/src/Outputs/Debugbar.php index 31ff9c0..094b8c0 100644 --- a/src/Outputs/Debugbar.php +++ b/src/Outputs/Debugbar.php @@ -15,8 +15,10 @@ class Debugbar implements Output public function boot() { $this->collector = new MessagesCollector('N+1 Queries'); - - LaravelDebugbar::addCollector($this->collector); + + if (!LaravelDebugbar::hasCollector($this->collector->getName())) { + LaravelDebugbar::addCollector($this->collector); + } } public function output(Collection $detectedQueries, Response $response) From 22ed53c198fe0425a0d6e9cdfb43d63579108602 Mon Sep 17 00:00:00 2001 From: Micheal Mand Date: Sun, 12 May 2019 14:50:07 -0600 Subject: [PATCH 42/72] Fix Facade usage If someone (like me) doesn't allow Debugbar to be auto-discovered by Laravel, the Facade might not be aliased to `Debugbar`. The exception `Class 'Debugbar' not found` would be thrown. --- src/Outputs/Debugbar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Outputs/Debugbar.php b/src/Outputs/Debugbar.php index 31ff9c0..3fc0529 100644 --- a/src/Outputs/Debugbar.php +++ b/src/Outputs/Debugbar.php @@ -5,7 +5,7 @@ use Illuminate\Support\Collection; use Symfony\Component\HttpFoundation\Response; -use Debugbar as LaravelDebugbar; +use Barryvdh\Debugbar\Facade as LaravelDebugbar; use DebugBar\DataCollector\MessagesCollector; class Debugbar implements Output From 8b1ee3e219185b0bde8b473028061d9481fc4455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danie=CC=88l=20de=20Wit?= Date: Tue, 17 Sep 2019 16:40:15 +0200 Subject: [PATCH 43/72] Add Laravel 6 support Replaced array_ helpers with underlying classes --- composer.json | 2 +- src/QueryDetector.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 6960203..a68a093 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^7.1", - "illuminate/support": "5.5.*|5.6.*|5.7.*|5.8.*" + "illuminate/support": "^5.5|^6" }, "require-dev": { "orchestra/testbench": "3.6.*", diff --git a/src/QueryDetector.php b/src/QueryDetector.php index 0e24f99..d9c1863 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -3,6 +3,7 @@ namespace BeyondCode\QueryDetector; use DB; +use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Database\Eloquent\Builder; use Symfony\Component\HttpFoundation\Response; @@ -47,7 +48,7 @@ public function isEnabled(): bool public function logQuery($query, Collection $backtrace) { $modelTrace = $backtrace->first(function ($trace) { - return array_get($trace, 'object') instanceof Builder; + return Arr::get($trace, 'object') instanceof Builder; }); // The query is coming from an Eloquent model @@ -57,7 +58,7 @@ public function logQuery($query, Collection $backtrace) * or if the class itself is a Relation. */ $relation = $backtrace->first(function ($trace) { - return array_get($trace, 'function') === 'getRelationValue' || array_get($trace, 'class') === Relation::class ; + return Arr::get($trace, 'function') === 'getRelationValue' || Arr::get($trace, 'class') === Relation::class ; }); // We try to access a relation @@ -76,8 +77,8 @@ public function logQuery($query, Collection $backtrace) $key = md5($query->sql . $model . $relationName . $sources[0]->name . $sources[0]->line); - $count = array_get($this->queries, $key.'.count', 0); - $time = array_get($this->queries, $key.'.time', 0); + $count = Arr::get($this->queries, $key.'.count', 0); + $time = Arr::get($this->queries, $key.'.time', 0); $this->queries[$key] = [ 'count' => ++$count, From 4b65a19b5e6cd775f9316ee3660ca3086e453906 Mon Sep 17 00:00:00 2001 From: "@oele_co" Date: Thu, 20 Feb 2020 15:20:02 -0500 Subject: [PATCH 44/72] Prevent Illegal string offset 'warning_queries' Prevent Illegal string offset 'warning_queries' exception from not Arrayable responses. --- src/Outputs/Json.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Outputs/Json.php b/src/Outputs/Json.php index 21b387e..e2f5714 100644 --- a/src/Outputs/Json.php +++ b/src/Outputs/Json.php @@ -16,6 +16,10 @@ public function output(Collection $detectedQueries, Response $response) { if ($response instanceof JsonResponse) { $data = $response->getData(true); + if (! is_array($data)){ + $data = [ $data ]; + } + $data['warning_queries'] = $detectedQueries; $response->setData($data); } From 623075d40ae03823cf372dfc2f52326eb83faf47 Mon Sep 17 00:00:00 2001 From: Matthew Nessworthy Date: Thu, 5 Mar 2020 10:21:55 +0100 Subject: [PATCH 45/72] Laravel 7 Support --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a68a093..314b670 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^7.1", - "illuminate/support": "^5.5|^6" + "illuminate/support": "^5.5|^6|^7" }, "require-dev": { "orchestra/testbench": "3.6.*", From b0b920b21f1519a75b012b29aeaae91be35061f0 Mon Sep 17 00:00:00 2001 From: Matthew Nessworthy Date: Mon, 9 Mar 2020 17:33:02 +0100 Subject: [PATCH 46/72] Test different laravel versions --- .travis.yml | 39 +++++++++++++++++++++++++++++++++------ composer.json | 6 +++--- tests/TestCase.php | 4 ++-- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 24c2d6c..ddfd84f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,15 +4,42 @@ php: - 7.1 - 7.2 - 7.3 + - 7.4 env: - matrix: - - COMPOSER_FLAGS="--prefer-lowest" - - COMPOSER_FLAGS="" + - LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" + - LARAVEL="^5.5" COMPOSER_FLAGS="" + - LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" + - LARAVEL="^6.0" COMPOSER_FLAGS="" + - LARAVEL="^7.0" COMPOSER_FLAGS="--prefer-lowest" + - LARAVEL="^7.0" COMPOSER_FLAGS="" -before_script: - - travis_retry composer self-update - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-source +matrix: + exclude: + - php: 7.1 + env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" + - php: 7.1 + env: LARAVEL="^6.0" COMPOSER_FLAGS="" + - php: 7.1 + env: LARAVEL="^7.0" COMPOSER_FLAGS="--prefer-lowest" + - php: 7.1 + env: LARAVEL="^7.0" COMPOSER_FLAGS="" + allow_failures: + - php: 7.4 + env: LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" + - php: 7.4 + env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" + +cache: + directories: + - $HOME/.composer/cache/files + +before_install: + - echo "memory_limit=2G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + +install: + - travis_retry composer require laravel/framework:${LARAVEL} --no-interaction --prefer-dist + - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist script: - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover diff --git a/composer.json b/composer.json index 314b670..9db0a09 100644 --- a/composer.json +++ b/composer.json @@ -17,11 +17,11 @@ ], "require": { "php": "^7.1", - "illuminate/support": "^5.5|^6|^7" + "illuminate/support": "^5.5 || ^6.0 || ^7.0" }, "require-dev": { - "orchestra/testbench": "3.6.*", - "phpunit/phpunit": "^7.0" + "orchestra/testbench": "^3.0 || ^4.0 || ^5.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "autoload": { "psr-4": { diff --git a/tests/TestCase.php b/tests/TestCase.php index 6f669c4..b981a0a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,7 +12,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase { protected static $setUpRun = false; - public function setUp() + public function setUp(): void { parent::setUp(); @@ -79,4 +79,4 @@ protected function setUpDatabase() $table->morphs('commentable'); }); } -} \ No newline at end of file +} From 548cc1d08179dc4edea24d38da5644a170467d04 Mon Sep 17 00:00:00 2001 From: Zlatoslav Desyatnikov Date: Fri, 3 Apr 2020 16:38:12 +0300 Subject: [PATCH 47/72] Ability to change queries treshold via .env --- README.md | 2 +- config/config.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 880e79a..f39b763 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ return [ * Threshold level for the N+1 query detection. If a relation query will be * executed more then this amount, the detector will notify you about it. */ - 'threshold' => 1, + 'threshold' => (int) env('QUERY_DETECTOR_TRESHOLD', 1), /* * Here you can whitelist model relations. diff --git a/config/config.php b/config/config.php index aa058d8..9ee1bb9 100644 --- a/config/config.php +++ b/config/config.php @@ -11,7 +11,7 @@ * Threshold level for the N+1 query detection. If a relation query will be * executed more then this amount, the detector will notify you about it. */ - 'threshold' => 1, + 'threshold' => (int) env('QUERY_DETECTOR_TRESHOLD', 1), /* * Here you can whitelist model relations. From 450443362eca1157b7d54df7a89a935d78e2e248 Mon Sep 17 00:00:00 2001 From: Daniel Breves Date: Wed, 6 May 2020 18:08:14 +1000 Subject: [PATCH 48/72] Avoid namespace conflicts --- src/Outputs/Log.php | 2 +- src/QueryDetector.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Outputs/Log.php b/src/Outputs/Log.php index 9aa2c18..874b395 100644 --- a/src/Outputs/Log.php +++ b/src/Outputs/Log.php @@ -2,7 +2,7 @@ namespace BeyondCode\QueryDetector\Outputs; -use Log as LaravelLog; +use Illuminate\Support\Facades\Log as LaravelLog; use Illuminate\Support\Collection; use Symfony\Component\HttpFoundation\Response; diff --git a/src/QueryDetector.php b/src/QueryDetector.php index d9c1863..0d3dcc6 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -2,7 +2,7 @@ namespace BeyondCode\QueryDetector; -use DB; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Database\Eloquent\Builder; From 9938d200b4d75b6b4d374fdc79a0669b756e2e97 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 20 May 2020 00:25:27 +0200 Subject: [PATCH 49/72] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 880e79a..b4199f7 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ If you rather want this information to be written to your `laravel.log` file, wr You can publish the package's configuration using this command: ```bash -php artisan vendor:publish --provider=BeyondCode\QueryDetector\QueryDetectorServiceProvider +php artisan vendor:publish --provider="BeyondCode\QueryDetector\QueryDetectorServiceProvider" ``` This will add the `querydetector.php` file in your config directory with the following contents: From 5d3bdd0a7d47b0960fb27ab9ffb453e6c181e7e9 Mon Sep 17 00:00:00 2001 From: Arie Visser Date: Fri, 22 May 2020 14:27:30 +0200 Subject: [PATCH 50/72] Fixed typo in threshold --- README.md | 2 +- config/config.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 755f34c..88a85ca 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ return [ * Threshold level for the N+1 query detection. If a relation query will be * executed more then this amount, the detector will notify you about it. */ - 'threshold' => (int) env('QUERY_DETECTOR_TRESHOLD', 1), + 'threshold' => (int) env('QUERY_DETECTOR_THRESHOLD', 1), /* * Here you can whitelist model relations. diff --git a/config/config.php b/config/config.php index 9ee1bb9..e4a6e06 100644 --- a/config/config.php +++ b/config/config.php @@ -11,7 +11,7 @@ * Threshold level for the N+1 query detection. If a relation query will be * executed more then this amount, the detector will notify you about it. */ - 'threshold' => (int) env('QUERY_DETECTOR_TRESHOLD', 1), + 'threshold' => (int) env('QUERY_DETECTOR_THRESHOLD', 1), /* * Here you can whitelist model relations. From de0233f6dabda777f71bc0e11be3ae45da4cf863 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 3 Jun 2020 16:33:42 +0200 Subject: [PATCH 51/72] wip --- .gitignore | 1 - docs/_index.md | 4 ++ docs/installation.md | 17 ++++++++ docs/usage.md | 92 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 docs/_index.md create mode 100644 docs/installation.md create mode 100644 docs/usage.md diff --git a/.gitignore b/.gitignore index 2e1fc0e..28367bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ build composer.lock -docs vendor coverage .idea diff --git a/docs/_index.md b/docs/_index.md new file mode 100644 index 0000000..ed8a55e --- /dev/null +++ b/docs/_index.md @@ -0,0 +1,4 @@ +--- +packageName: Laravel Query Detector +githubUrl: https://github.com/beyondcode/laravel-query-detector +--- \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..3559ca2 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,17 @@ +--- +title: Installation +order: 1 +--- +# Laravel N+1 Query Detector + +The Laravel N+1 query detector helps you to increase your application's performance by reducing the number of queries it executes. This package monitors your queries in real-time, while you develop your application and notify you when you should add eager loading (N+1 queries). + +# Installation + +You can install the package via composer: + +``` +composer require beyondcode/laravel-query-detector --dev +``` + +The package will automatically register itself. \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..be34cfd --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,92 @@ +--- +title: Usage +order: 2 +--- + +## Usage + +If you run your application in the `debug` mode, the query monitor will be automatically active. So there is nothing you have to do. + +By default, this package will display an `alert()` message to notify you about an N+1 query found in the current request. + +If you rather want this information to be written to your `laravel.log` file, written to your browser's console log as a warning or listed in a new tab for the [Laravel Debugbar (barryvdh/laravel-debugbar)](https://github.com/barryvdh/laravel-debugbar), you can publish the configuration and change the output behaviour (see example below). + +You can publish the package's configuration using this command: + +```bash +php artisan vendor:publish --provider="BeyondCode\QueryDetector\QueryDetectorServiceProvider" +``` + +This will add the `querydetector.php` file in your config directory with the following contents: + +```php +return [ + /* + * Enable or disable the query detection. + * If this is set to "null", the app.debug config value will be used. + */ + 'enabled' => env('QUERY_DETECTOR_ENABLED', null), + + /* + * Threshold level for the N+1 query detection. If a relation query will be + * executed more then this amount, the detector will notify you about it. + */ + 'threshold' => (int) env('QUERY_DETECTOR_THRESHOLD', 1), + + /* + * Here you can whitelist model relations. + * + * Right now, you need to define the model relation both as the class name and the attribute name on the model. + * So if an "Author" model would have a "posts" relation that points to a "Post" class, you need to add both + * the "posts" attribute and the "Post::class", since the relation can get resolved in multiple ways. + */ + 'except' => [ + //Author::class => [ + // Post::class, + // 'posts', + //] + ], + + /* + * Define the output format that you want to use. Multiple classes are supported. + * Available options are: + * + * Alert: + * Displays an alert on the website + * \BeyondCode\QueryDetector\Outputs\Alert::class + * + * Console: + * Writes the N+1 queries into your browsers console log + * \BeyondCode\QueryDetector\Outputs\Console::class + * + * Clockwork: (make sure you have the itsgoingd/clockwork package installed) + * Writes the N+1 queries warnings to Clockwork log + * \BeyondCode\QueryDetector\Outputs\Clockwork::class + * + * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) + * Writes the N+1 queries into a custom messages collector of Debugbar + * \BeyondCode\QueryDetector\Outputs\Debugbar::class + * + * JSON: + * Writes the N+1 queries into the response body of your JSON responses + * \BeyondCode\QueryDetector\Outputs\Json::class + * + * Log: + * Writes the N+1 queries into the Laravel.log file + * \BeyondCode\QueryDetector\Outputs\Log::class + */ + 'output' => [ + \BeyondCode\QueryDetector\Outputs\Log::class, + \BeyondCode\QueryDetector\Outputs\Alert::class, + ] + +]; +``` + +If you use **Lumen**, you need to copy the config file manually and register the Lumen Service Provider in `bootstrap/app.php` file + +```php +$app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class); +``` + +If you need additional logic to run when the package detects unoptimized queries, you can listen to the `\BeyondCode\QueryDetector\Events\QueryDetected` event and write a listener to run your own handler. (e.g. send warning to Sentry/Bugsnag, send Slack notification, etc.) From d18e95bc093c261514a278f8a34c4b8879f7c59f Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 3 Jun 2020 16:35:00 +0200 Subject: [PATCH 52/72] Update README.md --- README.md | 91 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 88a85ca..e356d24 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,6 @@ The Laravel N+1 query detector helps you to increase your application's performa ![Example alert](https://beyondco.de/github/n+1/alert.png) -> If you want to learn how to create reusable PHP packages yourself, take a look at my upcoming [PHP Package Development](https://phppackagedevelopment.com) video course. - ## Installation @@ -22,95 +20,10 @@ composer require beyondcode/laravel-query-detector --dev The package will automatically register itself. -## Usage - -If you run your application in the `debug` mode, the query monitor will be automatically active. So there is nothing you have to do. - -By default, this package will display an `alert()` message to notify you about an N+1 query found in the current request. - -If you rather want this information to be written to your `laravel.log` file, written to your browser's console log as a warning or listed in a new tab for the [Laravel Debugbar (barryvdh/laravel-debugbar)](https://github.com/barryvdh/laravel-debugbar), you can publish the configuration and change the output behaviour (see example below). - -You can publish the package's configuration using this command: - -```bash -php artisan vendor:publish --provider="BeyondCode\QueryDetector\QueryDetectorServiceProvider" -``` - -This will add the `querydetector.php` file in your config directory with the following contents: - -```php - env('QUERY_DETECTOR_ENABLED', null), - - /* - * Threshold level for the N+1 query detection. If a relation query will be - * executed more then this amount, the detector will notify you about it. - */ - 'threshold' => (int) env('QUERY_DETECTOR_THRESHOLD', 1), - - /* - * Here you can whitelist model relations. - * - * Right now, you need to define the model relation both as the class name and the attribute name on the model. - * So if an "Author" model would have a "posts" relation that points to a "Post" class, you need to add both - * the "posts" attribute and the "Post::class", since the relation can get resolved in multiple ways. - */ - 'except' => [ - //Author::class => [ - // Post::class, - // 'posts', - //] - ], - - /* - * Define the output format that you want to use. Multiple classes are supported. - * Available options are: - * - * Alert: - * Displays an alert on the website - * \BeyondCode\QueryDetector\Outputs\Alert::class - * - * Console: - * Writes the N+1 queries into your browsers console log - * \BeyondCode\QueryDetector\Outputs\Console::class - * - * Clockwork: (make sure you have the itsgoingd/clockwork package installed) - * Writes the N+1 queries warnings to Clockwork log - * \BeyondCode\QueryDetector\Outputs\Clockwork::class - * - * Debugbar: (make sure you have the barryvdh/laravel-debugbar package installed) - * Writes the N+1 queries into a custom messages collector of Debugbar - * \BeyondCode\QueryDetector\Outputs\Debugbar::class - * - * JSON: - * Writes the N+1 queries into the response body of your JSON responses - * \BeyondCode\QueryDetector\Outputs\Json::class - * - * Log: - * Writes the N+1 queries into the Laravel.log file - * \BeyondCode\QueryDetector\Outputs\Log::class - */ - 'output' => [ - \BeyondCode\QueryDetector\Outputs\Log::class, - \BeyondCode\QueryDetector\Outputs\Alert::class, - ] - -]; -``` - -If you use **Lumen**, you need to copy the config file manually and register the Lumen Service Provider in `bootstrap/app.php` file +## Documentation -```php -$app->register(\BeyondCode\QueryDetector\LumenQueryDetectorServiceProvider::class); -``` +You can find the documentation on our [website](http://beyondco.de/docs/laravel-query-detector). -If you need additional logic to run when the package detects unoptimized queries, you can listen to the `\BeyondCode\QueryDetector\Events\QueryDetected` event and write a listener to run your own handler. (e.g. send warning to Sentry/Bugsnag, send Slack notification, etc.) ### Testing From d868a211f1254a775e41c69b57f3d351160b446b Mon Sep 17 00:00:00 2001 From: Gianluca Bine Date: Tue, 8 Sep 2020 20:29:17 -0300 Subject: [PATCH 53/72] Laravel 8 support --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 9db0a09..f7045f2 100644 --- a/composer.json +++ b/composer.json @@ -17,10 +17,11 @@ ], "require": { "php": "^7.1", - "illuminate/support": "^5.5 || ^6.0 || ^7.0" + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { - "orchestra/testbench": "^3.0 || ^4.0 || ^5.0", + "laravel/legacy-factories": "^1.0", + "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "autoload": { From eddeac684a1aadd874dff1b68f5bdefebde05977 Mon Sep 17 00:00:00 2001 From: matt trask Date: Thu, 10 Dec 2020 11:06:10 -0600 Subject: [PATCH 54/72] allow for query logger to write to different logs --- config/config.php | 9 ++++++++- src/Outputs/Log.php | 13 +++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/config/config.php b/config/config.php index e4a6e06..03f5ec7 100644 --- a/config/config.php +++ b/config/config.php @@ -6,7 +6,7 @@ * If this is set to "null", the app.debug config value will be used. */ 'enabled' => env('QUERY_DETECTOR_ENABLED', null), - + /* * Threshold level for the N+1 query detection. If a relation query will be * executed more then this amount, the detector will notify you about it. @@ -27,6 +27,13 @@ //] ], + /* + * Here you can set a specific log channel to write to + * in case you are trying to isolate queries or have a lot + * going on in the laravel.log. Defaults to laravel.log though. + */ + 'log_channel' => env('QUERY_DETECTOR_LOG_CHANNEL', 'daily'), + /* * Define the output format that you want to use. Multiple classes are supported. * Available options are: diff --git a/src/Outputs/Log.php b/src/Outputs/Log.php index 874b395..7563530 100644 --- a/src/Outputs/Log.php +++ b/src/Outputs/Log.php @@ -15,22 +15,27 @@ public function boot() public function output(Collection $detectedQueries, Response $response) { - LaravelLog::info('Detected N+1 Query'); + $this->log('Detected N+1 Query'); foreach ($detectedQueries as $detectedQuery) { $logOutput = 'Model: '.$detectedQuery['model'] . PHP_EOL; - + $logOutput .= 'Relation: '.$detectedQuery['relation'] . PHP_EOL; $logOutput .= 'Num-Called: '.$detectedQuery['count'] . PHP_EOL; - + $logOutput .= 'Call-Stack:' . PHP_EOL; foreach ($detectedQuery['sources'] as $source) { $logOutput .= '#'.$source->index.' '.$source->name.':'.$source->line . PHP_EOL; } - LaravelLog::info($logOutput); + $this->log($logOutput); } } + + private function log(string $message) + { + LaravelLog::channel(config('querydetector.log_channel'))->info($message); + } } From f8f3652b8b665f30fb8cf7c18016777bc1c07363 Mon Sep 17 00:00:00 2001 From: Liam O'Connor <65899150+liamjoc@users.noreply.github.com> Date: Sat, 6 Feb 2021 13:12:05 +0000 Subject: [PATCH 55/72] Update .scrutinizer.yml --- .scrutinizer.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index df16b68..7f6f12d 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,5 +1,12 @@ filter: excluded_paths: [tests/*] + +build: + nodes: + analysis: + tests: + override: + - php-scrutinizer-run checks: php: From 94fc4d747b1569b027d188dc6dd15ee98e9785a3 Mon Sep 17 00:00:00 2001 From: Liam O'Connor Date: Sat, 6 Feb 2021 13:29:28 +0000 Subject: [PATCH 56/72] support php 8 in ci --- .travis.yml | 12 ++++++++++++ composer.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ddfd84f..2eb3583 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ php: - 7.2 - 7.3 - 7.4 + - 8.0 env: - LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" @@ -13,6 +14,8 @@ env: - LARAVEL="^6.0" COMPOSER_FLAGS="" - LARAVEL="^7.0" COMPOSER_FLAGS="--prefer-lowest" - LARAVEL="^7.0" COMPOSER_FLAGS="" + - LARAVEL="^8.0" COMPOSER_FLAGS="--prefer-lowest" + - LARAVEL="^8.0" COMPOSER_FLAGS="" matrix: exclude: @@ -24,11 +27,20 @@ matrix: env: LARAVEL="^7.0" COMPOSER_FLAGS="--prefer-lowest" - php: 7.1 env: LARAVEL="^7.0" COMPOSER_FLAGS="" + - php: 7.1 + env: LARAVEL="^8.0" COMPOSER_FLAGS="--prefer-lowest" + - php: 7.1 + env: LARAVEL="^8.0" COMPOSER_FLAGS="" allow_failures: - php: 7.4 env: LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" - php: 7.4 env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" + - php: 8.0 + env: LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" + - php: 8.0 + env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" + cache: directories: diff --git a/composer.json b/composer.json index f7045f2..efb3132 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^7.1", + "php": "^7.1 || ^8.0", "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { From 27a86e8860fce18b02ef52084d6aa8d0055708b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20L=C3=BCscher?= Date: Wed, 23 Jun 2021 10:56:20 +0000 Subject: [PATCH 57/72] Add slashes to relation strings in console output --- src/Outputs/Console.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Outputs/Console.php b/src/Outputs/Console.php index 6b4680f..7a90366 100644 --- a/src/Outputs/Console.php +++ b/src/Outputs/Console.php @@ -42,10 +42,10 @@ protected function getOutputContent(Collection $detectedQueries) $output .= "console.warn('Found the following N+1 queries in this request:\\n\\n"; foreach ($detectedQueries as $detectedQuery) { $output .= "Model: ".addslashes($detectedQuery['model'])." => Relation: ".addslashes($detectedQuery['relation']); - $output .= " - You should add \"with(\'".$detectedQuery['relation']."\')\" to eager-load this relation."; + $output .= " - You should add \"with(\'".addslashes($detectedQuery['relation'])."\')\" to eager-load this relation."; $output .= "\\n\\n"; $output .= "Model: ".addslashes($detectedQuery['model'])."\\n"; - $output .= "Relation: ".$detectedQuery['relation']."\\n"; + $output .= "Relation: ".addslashes($detectedQuery['relation'])."\\n"; $output .= "Num-Called: ".$detectedQuery['count']."\\n"; $output .= "\\n"; $output .= 'Call-Stack:\\n'; From 330113bb34f7b5809db5ef3e92566a0549cc4f21 Mon Sep 17 00:00:00 2001 From: Gustiawan Ouwawi Date: Wed, 9 Feb 2022 13:54:04 +0700 Subject: [PATCH 58/72] Update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index efb3132..46eb9e9 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ } ], "require": { - "php": "^7.1 || ^8.0", - "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0" + "php": "^8.0", + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { "laravel/legacy-factories": "^1.0", From befd883de2eeffa8956d52018919da33428b8dae Mon Sep 17 00:00:00 2001 From: Gustiawan Ouwawi Date: Wed, 9 Feb 2022 17:17:35 +0700 Subject: [PATCH 59/72] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 46eb9e9..ceafd91 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^8.0", + "php": "^7.1 || ^8.0", "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { From 51aca02bc82d1a26457e08f693ef0ad7def2b4f1 Mon Sep 17 00:00:00 2001 From: Scott Zirkel Date: Wed, 21 Sep 2022 11:09:45 -0500 Subject: [PATCH 60/72] Update QueryDetector.php Return if no sources are found. --- src/QueryDetector.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/QueryDetector.php b/src/QueryDetector.php index 0d3dcc6..8deb29a 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -74,6 +74,10 @@ public function logQuery($query, Collection $backtrace) } $sources = $this->findSource($backtrace); + + if (empty($sources)) { + return; + } $key = md5($query->sql . $model . $relationName . $sources[0]->name . $sources[0]->line); From d12d3b05dd9adec949603d05084ce6cd73e1fb5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Vdovec?= Date: Tue, 11 Oct 2022 10:46:52 +0200 Subject: [PATCH 61/72] Fix typo - then -> than --- config/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.php b/config/config.php index 03f5ec7..84f1765 100644 --- a/config/config.php +++ b/config/config.php @@ -9,7 +9,7 @@ /* * Threshold level for the N+1 query detection. If a relation query will be - * executed more then this amount, the detector will notify you about it. + * executed more than this amount, the detector will notify you about it. */ 'threshold' => (int) env('QUERY_DETECTOR_THRESHOLD', 1), From 60f0e5602315287c0f5bb9c8854fcda74f9999fc Mon Sep 17 00:00:00 2001 From: Shift Date: Mon, 30 Jan 2023 16:35:54 +0000 Subject: [PATCH 62/72] Bump dependencies for Laravel 10 --- composer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index ceafd91..23ff06e 100644 --- a/composer.json +++ b/composer.json @@ -17,11 +17,11 @@ ], "require": { "php": "^7.1 || ^8.0", - "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0" }, "require-dev": { "laravel/legacy-factories": "^1.0", - "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "autoload": { @@ -37,7 +37,6 @@ "scripts": { "test": "vendor/bin/phpunit", "test-coverage": "vendor/bin/phpunit --coverage-html coverage" - }, "config": { "sort-packages": true From 5e0a19c30e4cb9ac2a56851264e0fedbbeb81649 Mon Sep 17 00:00:00 2001 From: Kewei Yan Date: Thu, 2 Feb 2023 09:51:38 +0800 Subject: [PATCH 63/72] Add empty queries feature --- .gitignore | 3 ++- src/QueryDetector.php | 5 +++++ tests/QueryDetectorTest.php | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 28367bb..219f39f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ composer.lock vendor coverage .idea -nbproject \ No newline at end of file +nbproject +.phpunit.result.cache diff --git a/src/QueryDetector.php b/src/QueryDetector.php index 0d3dcc6..2d31478 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -213,4 +213,9 @@ public function output($request, $response) return $response; } + + public function emptyQueries() + { + $this->queries = Collection::make(); + } } diff --git a/tests/QueryDetectorTest.php b/tests/QueryDetectorTest.php index b428e2a..97cf4ff 100644 --- a/tests/QueryDetectorTest.php +++ b/tests/QueryDetectorTest.php @@ -288,4 +288,27 @@ public function it_uses_the_trace_line_to_detect_queries() $this->assertSame(Author::class, $queries[0]['model']); $this->assertSame('profile', $queries[0]['relation']); } + + /** @test */ + public function it_empty_queries() + { + Route::get('/', function (){ + $authors = Author::all(); + + foreach ($authors as $author) { + $author->profile; + } + }); + + $this->get('/'); + + $queryDetector = app(QueryDetector::class); + + $queries = $queryDetector->getDetectedQueries(); + $this->assertCount(1, $queries); + + $queryDetector->emptyQueries(); + $queries = $queryDetector->getDetectedQueries(); + $this->assertCount(0, $queries); + } } From 4aa22690155dc96ee80271938ca919f0408fcef7 Mon Sep 17 00:00:00 2001 From: steve-moretz Date: Fri, 15 Sep 2023 17:36:02 +0330 Subject: [PATCH 64/72] Support multiple requests --- src/QueryDetector.php | 32 ++++++++++++++++++------- tests/QueryDetectorTest.php | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/QueryDetector.php b/src/QueryDetector.php index 0d3dcc6..4832a3b 100755 --- a/src/QueryDetector.php +++ b/src/QueryDetector.php @@ -14,15 +14,29 @@ class QueryDetector { /** @var Collection */ private $queries; + /** + * @var bool + */ + private $booted = false; - public function __construct() + private function resetQueries() { $this->queries = Collection::make(); } + public function __construct() + { + $this->resetQueries(); + } + public function boot() { - DB::listen(function($query) { + if ($this->booted) { + $this->resetQueries(); + return; + } + + DB::listen(function ($query) { $backtrace = collect(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 50)); $this->logQuery($query, $backtrace); @@ -32,6 +46,8 @@ public function boot() app()->singleton($outputType); app($outputType)->boot(); } + + $this->booted = true; } public function isEnabled(): bool @@ -52,13 +68,13 @@ public function logQuery($query, Collection $backtrace) }); // The query is coming from an Eloquent model - if (! is_null($modelTrace)) { + if (!is_null($modelTrace)) { /* * Relations get resolved by either calling the "getRelationValue" method on the model, * or if the class itself is a Relation. */ $relation = $backtrace->first(function ($trace) { - return Arr::get($trace, 'function') === 'getRelationValue' || Arr::get($trace, 'class') === Relation::class ; + return Arr::get($trace, 'function') === 'getRelationValue' || Arr::get($trace, 'class') === Relation::class; }); // We try to access a relation @@ -77,8 +93,8 @@ public function logQuery($query, Collection $backtrace) $key = md5($query->sql . $model . $relationName . $sources[0]->name . $sources[0]->line); - $count = Arr::get($this->queries, $key.'.count', 0); - $time = Arr::get($this->queries, $key.'.time', 0); + $count = Arr::get($this->queries, $key . '.count', 0); + $time = Arr::get($this->queries, $key . '.time', 0); $this->queries[$key] = [ 'count' => ++$count, @@ -106,7 +122,7 @@ protected function findSource($stack) public function parseTrace($index, array $trace) { - $frame = (object) [ + $frame = (object)[ 'index' => $index, 'name' => null, 'line' => isset($trace['line']) ? $trace['line'] : '?', @@ -191,7 +207,7 @@ protected function getOutputTypes() { $outputTypes = config('querydetector.output'); - if (! is_array($outputTypes)) { + if (!is_array($outputTypes)) { $outputTypes = [$outputTypes]; } diff --git a/tests/QueryDetectorTest.php b/tests/QueryDetectorTest.php index b428e2a..b467d85 100644 --- a/tests/QueryDetectorTest.php +++ b/tests/QueryDetectorTest.php @@ -34,6 +34,54 @@ public function it_detects_n1_query_on_properties() $this->assertSame('profile', $queries[0]['relation']); } + /** @test */ + public function it_detects_n1_query_on_multiple_requests() + { + Route::get('/', function (){ + $authors = Author::get(); + + foreach ($authors as $author) { + $author->profile; + } + }); + + // first request + $this->get('/'); + $queries = app(QueryDetector::class)->getDetectedQueries(); + $this->assertCount(1, $queries); + $this->assertSame(Author::count(), $queries[0]['count']); + $this->assertSame(Author::class, $queries[0]['model']); + $this->assertSame('profile', $queries[0]['relation']); + + // second request + $this->get('/'); + $queries = app(QueryDetector::class)->getDetectedQueries(); + $this->assertCount(1, $queries); + $this->assertSame(Author::count(), $queries[0]['count']); + $this->assertSame(Author::class, $queries[0]['model']); + $this->assertSame('profile', $queries[0]['relation']); + } + + /** @test */ + public function it_does_not_detect_a_false_n1_query_on_multiple_requests() + { + Route::get('/', function (){ + $authors = Author::with("profile")->get(); + + foreach ($authors as $author) { + $author->profile; + } + }); + + // first request + $this->get('/'); + $this->assertCount(0, app(QueryDetector::class)->getDetectedQueries()); + + // second request + $this->get('/'); + $this->assertCount(0, app(QueryDetector::class)->getDetectedQueries()); + } + /** @test */ public function it_ignores_eager_loaded_relationships() { From 70d2888d46c94a148451a450bccf1bafbd7b6066 Mon Sep 17 00:00:00 2001 From: Shift Date: Fri, 1 Mar 2024 22:17:48 +0000 Subject: [PATCH 65/72] Bump dependencies for Laravel 11 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 23ff06e..1ca8543 100644 --- a/composer.json +++ b/composer.json @@ -17,12 +17,12 @@ ], "require": { "php": "^7.1 || ^8.0", - "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0" + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0 || ^11.0" }, "require-dev": { "laravel/legacy-factories": "^1.0", - "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0 || ^9.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0 || ^10.5" }, "autoload": { "psr-4": { From a4c3b344f9156a2046752e2f19d6b55ec8173606 Mon Sep 17 00:00:00 2001 From: Di Date: Fri, 4 Oct 2024 16:44:11 +0200 Subject: [PATCH 66/72] Closes #43 --- src/QueryDetectorServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QueryDetectorServiceProvider.php b/src/QueryDetectorServiceProvider.php index 8d62987..4efac27 100644 --- a/src/QueryDetectorServiceProvider.php +++ b/src/QueryDetectorServiceProvider.php @@ -15,7 +15,7 @@ public function boot() if ($this->app->runningInConsole()) { $this->publishes([ __DIR__.'/../config/config.php' => config_path('querydetector.php'), - ], 'config'); + ], 'query-detector-config'); } $this->registerMiddleware(QueryDetectorMiddleware::class); From 761a16ceae579df226643e15e0b70f9c8e8a1e43 Mon Sep 17 00:00:00 2001 From: Di Date: Fri, 4 Oct 2024 18:12:18 +0200 Subject: [PATCH 67/72] Updated README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index e356d24..dee3863 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Laravel N+1 Query Detector [![Latest Version on Packagist](https://img.shields.io/packagist/v/beyondcode/laravel-query-detector.svg?style=flat-square)](https://packagist.org/packages/beyondcode/laravel-query-detector) -[![Build Status](https://img.shields.io/travis/beyondcode/laravel-query-detector/master.svg?style=flat-square)](https://travis-ci.org/beyondcode/laravel-query-detector) -[![Quality Score](https://img.shields.io/scrutinizer/g/beyondcode/laravel-query-detector.svg?style=flat-square)](https://scrutinizer-ci.com/g/beyondcode/laravel-query-detector) [![Total Downloads](https://img.shields.io/packagist/dt/beyondcode/laravel-query-detector.svg?style=flat-square)](https://packagist.org/packages/beyondcode/laravel-query-detector) The Laravel N+1 query detector helps you to increase your application's performance by reducing the number of queries it executes. This package monitors your queries in real-time, while you develop your application and notify you when you should add eager loading (N+1 queries). From b9dc996fb8fe4f6b17e803994a151d66bd39440f Mon Sep 17 00:00:00 2001 From: Di Date: Fri, 4 Oct 2024 18:14:29 +0200 Subject: [PATCH 68/72] Removed old CI files --- .scrutinizer.yml | 26 --------------------- .styleci.yml | 4 ---- .travis.yml | 60 ------------------------------------------------ 3 files changed, 90 deletions(-) delete mode 100644 .scrutinizer.yml delete mode 100644 .styleci.yml delete mode 100644 .travis.yml diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 7f6f12d..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,26 +0,0 @@ -filter: - excluded_paths: [tests/*] - -build: - nodes: - analysis: - tests: - override: - - php-scrutinizer-run - -checks: - php: - remove_extra_empty_lines: true - remove_php_closing_tag: true - remove_trailing_whitespace: true - fix_use_statements: - remove_unused: true - preserve_multiple: false - preserve_blanklines: true - order_alphabetically: true - fix_php_opening_tag: true - fix_linefeed: true - fix_line_ending: true - fix_identation_4spaces: true - fix_doc_comments: true - diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index f4d3cbc..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,4 +0,0 @@ -preset: laravel - -disabled: - - single_class_element_per_statement diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2eb3583..0000000 --- a/.travis.yml +++ /dev/null @@ -1,60 +0,0 @@ -language: php - -php: - - 7.1 - - 7.2 - - 7.3 - - 7.4 - - 8.0 - -env: - - LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" - - LARAVEL="^5.5" COMPOSER_FLAGS="" - - LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" - - LARAVEL="^6.0" COMPOSER_FLAGS="" - - LARAVEL="^7.0" COMPOSER_FLAGS="--prefer-lowest" - - LARAVEL="^7.0" COMPOSER_FLAGS="" - - LARAVEL="^8.0" COMPOSER_FLAGS="--prefer-lowest" - - LARAVEL="^8.0" COMPOSER_FLAGS="" - -matrix: - exclude: - - php: 7.1 - env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" - - php: 7.1 - env: LARAVEL="^6.0" COMPOSER_FLAGS="" - - php: 7.1 - env: LARAVEL="^7.0" COMPOSER_FLAGS="--prefer-lowest" - - php: 7.1 - env: LARAVEL="^7.0" COMPOSER_FLAGS="" - - php: 7.1 - env: LARAVEL="^8.0" COMPOSER_FLAGS="--prefer-lowest" - - php: 7.1 - env: LARAVEL="^8.0" COMPOSER_FLAGS="" - allow_failures: - - php: 7.4 - env: LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" - - php: 7.4 - env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" - - php: 8.0 - env: LARAVEL="^5.5" COMPOSER_FLAGS="--prefer-lowest" - - php: 8.0 - env: LARAVEL="^6.0" COMPOSER_FLAGS="--prefer-lowest" - - -cache: - directories: - - $HOME/.composer/cache/files - -before_install: - - echo "memory_limit=2G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - -install: - - travis_retry composer require laravel/framework:${LARAVEL} --no-interaction --prefer-dist - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist - -script: - - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - -after_script: - - php vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover From a6989b0a8b59bd5f8587919f332eedab9a8c0a45 Mon Sep 17 00:00:00 2001 From: Shift Date: Mon, 17 Feb 2025 01:59:14 +0000 Subject: [PATCH 69/72] Bump dependencies for Laravel 12 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 1ca8543..e6da0e9 100644 --- a/composer.json +++ b/composer.json @@ -17,12 +17,12 @@ ], "require": { "php": "^7.1 || ^8.0", - "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0 || ^11.0" + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0|^10.0 || ^11.0 || ^12.0" }, "require-dev": { "laravel/legacy-factories": "^1.0", - "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0 || ^9.0", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0 || ^10.5" + "orchestra/testbench": "^3.0 || ^4.0 || ^5.0 || ^6.0|^8.0 || ^9.0 || ^10.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0 || ^10.5 || ^11.5.3" }, "autoload": { "psr-4": { From 387dfbd64b0dc92f16005a70ea407e8012b8e314 Mon Sep 17 00:00:00 2001 From: Diana Scharf Date: Tue, 11 Mar 2025 10:30:13 +0100 Subject: [PATCH 70/72] Updated phpunit.xml --- phpunit.xml.dist | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 1eef57c..5119f0b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,12 +1,7 @@ @@ -14,16 +9,4 @@ tests - - - src/ - - - - - - - - - From 2ed0bb5660f459c87156076bfbcd7d9b0dc4b530 Mon Sep 17 00:00:00 2001 From: Diana Scharf Date: Tue, 11 Mar 2025 10:30:28 +0100 Subject: [PATCH 71/72] Workflow --- .github/workflows/tests.yml | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..cd7da98 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,71 @@ +name: run-tests + +on: + push: + branches: + - master + - dev + pull_request: + branches: + - master + +jobs: + php-tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: ['8.4', '8.3', '8.2', '8.1', '8.0'] + laravel: ['8.*', '9.*', '10.*', '11.*', '12.*'] + dependency-version: [prefer-stable] + exclude: + - php: 8.0 + laravel: 10.* + - php: 8.0 + laravel: 11.* + - php: 8.0 + laravel: 12.* + - php: 8.1 + laravel: 11.* + - php: 8.1 + laravel: 12.* + - php: 8.2 + laravel: 8.* + - php: 8.3 + laravel: 8.* + - php: 8.4 + laravel: 8.* + include: + - laravel: 8.* + testbench: 6.23 + - laravel: 9.* + testbench: 7.* + - laravel: 10.* + testbench: 8.* + - laravel: 11.* + testbench: 9.* + - laravel: 12.* + testbench: 10.* + + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick + coverage: none + + - name: Install dependencies + run: | + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update + composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction + + - name: Execute tests + run: vendor/bin/phpunit \ No newline at end of file From ac1506d18f4133a76007f987983053ae6befa4ac Mon Sep 17 00:00:00 2001 From: Diana Scharf Date: Tue, 11 Mar 2025 10:33:20 +0100 Subject: [PATCH 72/72] Workflow --- .github/workflows/tests.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cd7da98..62d0391 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,8 +34,12 @@ jobs: laravel: 8.* - php: 8.3 laravel: 8.* + - php: 8.3 + laravel: 9.* - php: 8.4 laravel: 8.* + - php: 8.4 + laravel: 9.* include: - laravel: 8.* testbench: 6.23 @@ -48,7 +52,6 @@ jobs: - laravel: 12.* testbench: 10.* - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ubuntu-latest steps: