diff --git a/composer.lock b/composer.lock index cc501f52..0a6ba015 100644 --- a/composer.lock +++ b/composer.lock @@ -1051,12 +1051,12 @@ "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "eac3418dd5ff5c11dbaefee25038a734582f283a" + "reference": "1f3e086f00ab72b3459e38fd02293efbceabd597" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/eac3418dd5ff5c11dbaefee25038a734582f283a", - "reference": "eac3418dd5ff5c11dbaefee25038a734582f283a", + "url": "https://api.github.com/repos/laravel/framework/zipball/1f3e086f00ab72b3459e38fd02293efbceabd597", + "reference": "1f3e086f00ab72b3459e38fd02293efbceabd597", "shasum": "" }, "require": { @@ -1207,11 +1207,6 @@ }, "default-branch": true, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "11.x-dev" - } - }, "autoload": { "files": [ "src/Illuminate/Collections/helpers.php", @@ -1249,7 +1244,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-03-12T21:21:28+00:00" + "time": "2024-03-19T13:53:45+00:00" }, { "name": "laravel/prompts", @@ -1558,16 +1553,16 @@ }, { "name": "league/flysystem", - "version": "3.25.0", + "version": "3.25.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "4c44347133618cccd9b3df1729647a1577b4ad99" + "reference": "abbd664eb4381102c559d358420989f835208f18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4c44347133618cccd9b3df1729647a1577b4ad99", - "reference": "4c44347133618cccd9b3df1729647a1577b4ad99", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/abbd664eb4381102c559d358420989f835208f18", + "reference": "abbd664eb4381102c559d358420989f835208f18", "shasum": "" }, "require": { @@ -1632,7 +1627,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.25.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.25.1" }, "funding": [ { @@ -1644,20 +1639,20 @@ "type": "github" } ], - "time": "2024-03-09T17:06:45+00:00" + "time": "2024-03-16T12:53:19+00:00" }, { "name": "league/flysystem-local", - "version": "3.23.1", + "version": "3.25.1", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00" + "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/b884d2bf9b53bb4804a56d2df4902bb51e253f00", - "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/61a6a90d6e999e4ddd9ce5adb356de0939060b92", + "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92", "shasum": "" }, "require": { @@ -1691,8 +1686,7 @@ "local" ], "support": { - "issues": "https://github.com/thephpleague/flysystem-local/issues", - "source": "https://github.com/thephpleague/flysystem-local/tree/3.23.1" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.25.1" }, "funding": [ { @@ -1704,7 +1698,7 @@ "type": "github" } ], - "time": "2024-01-26T18:25:23+00:00" + "time": "2024-03-15T19:58:44+00:00" }, { "name": "league/mime-type-detection", @@ -1865,16 +1859,16 @@ }, { "name": "nesbot/carbon", - "version": "3.0.2", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "cf30cfceac9693bdb339ffb51f091e6039bdf10d" + "reference": "34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cf30cfceac9693bdb339ffb51f091e6039bdf10d", - "reference": "cf30cfceac9693bdb339ffb51f091e6039bdf10d", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2", + "reference": "34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2", "shasum": "" }, "require": { @@ -1967,7 +1961,7 @@ "type": "tidelift" } ], - "time": "2024-02-06T09:28:31+00:00" + "time": "2024-03-13T12:42:37+00:00" }, { "name": "nette/schema", @@ -5702,16 +5696,16 @@ }, { "name": "laravel/laravel", - "version": "v11.0.1", + "version": "v11.0.3", "source": { "type": "git", "url": "https://github.com/laravel/laravel.git", - "reference": "6ea57d766ffc7948adbf02b6ac63670d43580316" + "reference": "087543a48c35787fa67e4b69b79ae301824adeec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/laravel/zipball/6ea57d766ffc7948adbf02b6ac63670d43580316", - "reference": "6ea57d766ffc7948adbf02b6ac63670d43580316", + "url": "https://api.github.com/repos/laravel/laravel/zipball/087543a48c35787fa67e4b69b79ae301824adeec", + "reference": "087543a48c35787fa67e4b69b79ae301824adeec", "shasum": "" }, "require": { @@ -5730,9 +5724,6 @@ }, "type": "project", "extra": { - "branch-alias": { - "dev-master": "11.x-dev" - }, "laravel": { "dont-discover": [] } @@ -5754,9 +5745,9 @@ "laravel" ], "support": { - "source": "https://github.com/laravel/laravel/tree/v11.0.1" + "source": "https://github.com/laravel/laravel/tree/v11.0.3" }, - "time": "2024-03-12T18:20:16+00:00" + "time": "2024-03-14T13:51:29+00:00" }, { "name": "laravel/pint", @@ -6298,16 +6289,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.61", + "version": "1.10.63", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "30049da2df0941c38e2ba49372018aa796b90db4" + "reference": "ad12836d9ca227301f5fb9960979574ed8628339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/30049da2df0941c38e2ba49372018aa796b90db4", - "reference": "30049da2df0941c38e2ba49372018aa796b90db4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ad12836d9ca227301f5fb9960979574ed8628339", + "reference": "ad12836d9ca227301f5fb9960979574ed8628339", "shasum": "" }, "require": { @@ -6356,7 +6347,7 @@ "type": "tidelift" } ], - "time": "2024-03-13T09:49:39+00:00" + "time": "2024-03-18T16:53:53+00:00" }, { "name": "phpunit/php-code-coverage", @@ -6782,16 +6773,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.0", + "version": "v0.12.2", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d" + "reference": "9185c66c2165bbf4d71de78a69dccf4974f9538d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/750bf031a48fd07c673dbe3f11f72362ea306d0d", - "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/9185c66c2165bbf4d71de78a69dccf4974f9538d", + "reference": "9185c66c2165bbf4d71de78a69dccf4974f9538d", "shasum": "" }, "require": { @@ -6855,9 +6846,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.0" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.2" }, - "time": "2023-12-20T15:28:09+00:00" + "time": "2024-03-17T01:53:00+00:00" }, { "name": "sebastian/cli-parser", diff --git a/src/Actions/Action.php b/src/Actions/Action.php index 9d8df494..d0a6f3e4 100644 --- a/src/Actions/Action.php +++ b/src/Actions/Action.php @@ -2,6 +2,7 @@ namespace Cone\Root\Actions; +use Closure; use Cone\Root\Exceptions\QueryResolutionException; use Cone\Root\Fields\Field; use Cone\Root\Fields\Relation; @@ -59,9 +60,9 @@ abstract class Action implements Arrayable, Form, JsonSerializable protected bool $standalone = false; /** - * The Eloquent query. + * The query resolver. */ - protected ?Builder $query = null; + protected ?Closure $queryResolver = null; /** * Handle the action. @@ -101,25 +102,25 @@ public function getModalKey(): string } /** - * Set the Eloquent query. + * Resolve the query. */ - public function setQuery(Builder $query): static + public function resolveQuery(Request $request): Builder { - $this->query = $query; + if (is_null($this->queryResolver)) { + throw new QueryResolutionException(); + } - return $this; + return call_user_func_array($this->queryResolver, [$request]); } /** - * Get the Eloquent query. + * Set the query resolver callback. */ - public function getQuery(): Builder + public function withQuery(Closure $callback): static { - if (is_null($this->query)) { - throw new QueryResolutionException(); - } + $this->queryResolver = $callback; - return $this->query; + return $this; } /** @@ -203,8 +204,8 @@ public function handleFormRequest(Request $request, Model $model): void $models = match (true) { $this->isStandalone() => new Collection([$model]), - $request->boolean('all') => $this->getQuery()->get(), - default => $this->getQuery()->findMany($request->input('models', [])), + $request->boolean('all') => $this->resolveQuery($request)->get(), + default => $this->resolveQuery($request)->findMany($request->input('models', [])), }; $this->handle($request, $models); @@ -215,7 +216,7 @@ public function handleFormRequest(Request $request, Model $model): void */ public function perform(Request $request): Response { - $this->handleFormRequest($request, $this->getQuery()->getModel()); + $this->handleFormRequest($request, $this->resolveQuery($request)->getModel()); return Redirect::back()->with( sprintf('alerts.action-%s', $this->getKey()), @@ -273,7 +274,6 @@ public function toArray(): array 'modalKey' => $this->getModalKey(), 'name' => $this->getName(), 'template' => $this->template, - 'url' => $this->getUri(), ]; } @@ -283,6 +283,7 @@ public function toArray(): array public function toForm(Request $request, Model $model): array { return array_merge($this->toArray(), [ + 'url' => ! is_null($request->route()) ? $this->replaceRoutePlaceholders($request->route()) : null, 'open' => $this->errors($request)->isNotEmpty(), 'fields' => $this->resolveFields($request)->mapToInputs($request, $model), ]); diff --git a/src/Fields/Relation.php b/src/Fields/Relation.php index dcefe43b..749d595d 100644 --- a/src/Fields/Relation.php +++ b/src/Fields/Relation.php @@ -3,6 +3,7 @@ namespace Cone\Root\Fields; use Closure; +use Cone\Root\Actions\Action; use Cone\Root\Exceptions\SaveFormDataException; use Cone\Root\Filters\Filter; use Cone\Root\Filters\RenderableFilter; @@ -409,6 +410,18 @@ protected function resolveField(Request $request, Field $field): void } } + /** + * Handle the callback for the field resolution. + */ + protected function resolveAction(Request $request, Action $action): void + { + $action->withQuery(function (Request $request): Builder { + $model = $request->route('resourceModel'); + + return $this->resolveFilters($request)->apply($request, $this->getRelation($model)->getQuery()); + }); + } + /** * Handle the callback for the filter resolution. */ diff --git a/src/Resources/Resource.php b/src/Resources/Resource.php index acdd961c..4054fbb5 100644 --- a/src/Resources/Resource.php +++ b/src/Resources/Resource.php @@ -344,7 +344,7 @@ protected function resolveFilter(Request $request, Filter $filter): void */ protected function resolveAction(Request $request, Action $action): void { - $action->setQuery($this->resolveFilteredQuery($request)); + $action->withQuery(fn (): Builder => $this->resolveFilteredQuery($request)); } /** diff --git a/src/Widgets/Metric.php b/src/Widgets/Metric.php index a730380f..3c9fb5be 100644 --- a/src/Widgets/Metric.php +++ b/src/Widgets/Metric.php @@ -49,7 +49,7 @@ public function resolveQuery(Request $request): Builder /** * Set the query resolver callback. */ - public function resolverQueryUsing(Closure $callback): static + public function withQuery(Closure $callback): static { $this->queryResolver = $callback; diff --git a/tests/Actions/ActionTest.php b/tests/Actions/ActionTest.php index 3ec98594..3ac06370 100644 --- a/tests/Actions/ActionTest.php +++ b/tests/Actions/ActionTest.php @@ -5,6 +5,7 @@ use Cone\Root\Fields\Text; use Cone\Root\Tests\TestCase; use Cone\Root\Tests\User; +use Illuminate\Routing\Route; class ActionTest extends TestCase { @@ -16,7 +17,7 @@ public function setUp(): void $this->action = new SendPasswordResetNotification(); - $this->action->setQuery(User::query()); + $this->action->withQuery(fn () => User::query()); } public function test_an_action_has_key(): void @@ -91,7 +92,6 @@ public function test_an_action_has_array_representation(): void 'modalKey' => 'action-send-password-reset-notification', 'name' => $this->action->getName(), 'template' => 'root::actions.action', - 'url' => $this->action->getUri(), ], $this->action->toArray()); } @@ -99,11 +99,8 @@ public function test_an_action_has_form_representation(): void { $model = new User(); - $fields = $this->action - ->resolveFields($this->app['request']) - ->mapToInputs($this->app['request'], $model); - $this->assertSame(array_merge($this->action->toArray(), [ + 'url' => null, 'open' => false, 'fields' => [], ]), $this->action->toForm($this->app['request'], $model)); diff --git a/tests/Widgets/UsersCount.php b/tests/Widgets/UsersCount.php index ddb7db06..1735297a 100644 --- a/tests/Widgets/UsersCount.php +++ b/tests/Widgets/UsersCount.php @@ -2,9 +2,14 @@ namespace Cone\Root\Tests\Widgets; +use Cone\Root\Tests\User; use Cone\Root\Widgets\Value; +use Illuminate\Database\Eloquent\Builder; class UsersCount extends Value { - // + public function query(): Builder + { + return User::query(); + } } diff --git a/tests/Widgets/UsersTrend.php b/tests/Widgets/UsersTrend.php index c874ea3f..2b2ec115 100644 --- a/tests/Widgets/UsersTrend.php +++ b/tests/Widgets/UsersTrend.php @@ -2,9 +2,14 @@ namespace Cone\Root\Tests\Widgets; +use Cone\Root\Tests\User; use Cone\Root\Widgets\Trend; +use Illuminate\Database\Eloquent\Builder; class UsersTrend extends Trend { - // + public function query(): Builder + { + return User::query(); + } }