From a81d13e26c1c2191859493de2ad45a515ad07b90 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Thu, 12 Dec 2024 21:27:57 +0100 Subject: [PATCH] fix: beta.1 early bugs --- .../src/Api/Endpoint/Concerns/HasHooks.php | 4 +-- .../core/src/Database/Eloquent/Collection.php | 32 +++++++++++++++++++ framework/core/src/Extend/Console.php | 4 +-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/framework/core/src/Api/Endpoint/Concerns/HasHooks.php b/framework/core/src/Api/Endpoint/Concerns/HasHooks.php index a31cf4d890..2e91afbca5 100644 --- a/framework/core/src/Api/Endpoint/Concerns/HasHooks.php +++ b/framework/core/src/Api/Endpoint/Concerns/HasHooks.php @@ -40,7 +40,7 @@ protected function resolveCallable(callable|string $callable, Context $context): return $callable; } - protected function callBeforeHook(Context $context): void + public function callBeforeHook(Context $context): void { foreach ($this->before as $before) { $before = $this->resolveCallable($before, $context); @@ -48,7 +48,7 @@ protected function callBeforeHook(Context $context): void } } - protected function callAfterHook(Context $context, mixed $data): mixed + public function callAfterHook(Context $context, mixed $data): mixed { foreach ($this->after as $after) { $after = $this->resolveCallable($after, $context); diff --git a/framework/core/src/Database/Eloquent/Collection.php b/framework/core/src/Database/Eloquent/Collection.php index ec96d0d79e..ef5c5fe87d 100644 --- a/framework/core/src/Database/Eloquent/Collection.php +++ b/framework/core/src/Database/Eloquent/Collection.php @@ -54,4 +54,36 @@ public function loadAggregate($relations, $column, $function = null): self return parent::loadAggregate($relations, $column, $function); }); } + + /** + * The original Laravel logic uses ->whereNotNull() which is an abstraction that unnecessarily causes + * attribute mutators to run, so if a mutator relies on an eager loaded relationship, the mutator + * will be executed before the call to ->loadMissing() is over. + * + * We replace it with a simple ->where(fn (mixed $relation) => $relation !== null) to avoid this issue. + */ + protected function loadMissingRelation(BaseCollection $models, array $path): void + { + $relation = array_shift($path); + + $name = explode(':', key($relation))[0]; + + if (is_string(reset($relation))) { + $relation = reset($relation); + } + + $models->filter(fn ($model) => ! is_null($model) && ! $model->relationLoaded($name))->load($relation); + + if (empty($path)) { + return; + } + + $models = $models->pluck($name)->where(fn (mixed $relation) => $relation !== null); + + if ($models->first() instanceof \Illuminate\Support\Collection) { + $models = $models->collapse(); + } + + $this->loadMissingRelation(new static($models), $path); + } } diff --git a/framework/core/src/Extend/Console.php b/framework/core/src/Extend/Console.php index b05f233e8b..e90f5e8ed5 100644 --- a/framework/core/src/Extend/Console.php +++ b/framework/core/src/Extend/Console.php @@ -22,7 +22,7 @@ class Console implements ExtenderInterface /** * Add a command to the console. * - * @param class-string $command: ::class attribute of command class, which must extend \Flarum\Console\AbstractCommand. + * @param class-string $command: ::class attribute of command class, which must extend \Flarum\Console\AbstractCommand. * @return self */ public function command(string $command): self @@ -35,7 +35,7 @@ public function command(string $command): self /** * Schedule a command to run on an interval. * - * @param class-string $command: ::class attribute of command class, which must extend Flarum\Console\AbstractCommand. + * @param class-string $command: ::class attribute of command class, which must extend Flarum\Console\AbstractCommand. * @param (callable(\Illuminate\Console\Scheduling\Event $event): void)|class-string $callback * * The callback can be a closure or invokable class, and should accept: