parentState = $parent; } public function buildRecipes(): Recipe { $recipes = $this->getPrimaryCriteriedRecipes(); return $this->getSecondaryCriteriedRecipes($recipes); } public function getTagsCollection(): array { return Recipe::all()->map( fn ($r) => [ $r->type, $r->tags->map(fn ($t) => $t->id . '-' . $t->name)->all(), ] )->reduce(function ($acc, $item) { [$type, $tagNames] = $item; foreach ($tagNames as $name) { if (isset($acc[$type][$name])) { $acc[$type][$name] += 1; } else { $acc[$type][$name] = 1; } } return $acc; }); } private function getPrimaryCriteriedRecipes(): Builder|Recipe|MorphToMany|array { if ($this->parentState->author) { return $this->getAuthorRecipes(); } if ($this->parentState->tag) { return $this->getTagRecipes(); } if ($this->parentState->search && mb_strlen($this->parentState->search) > 2) { return $this->getSearchRecipes(); } return new Recipe(); } private function getSecondaryCriteriedRecipes(Builder|Recipe|MorphToMany|array $recipes): Recipe { if ($this->parentState->typeFilter === 'user') { $recipes = $recipes->whereRelation('author', 'is_consultant', false); } if ($this->parentState->typeFilter === 'consultant') { $recipes = $recipes->whereRelation('author', 'is_consultant', true); } return $recipes; } private function getAuthorRecipes(): array { $author = $this->parentState->author; $user = User::find($author); return $user ? $user->author_of_recipe() : []; } private function getTagRecipes(): MorphToMany { $tagId = Str::of($this->parentState->tag)->split('/-/')->first(); return Tag::find($tagId)->recipes(); } private function getSearchRecipes(): Builder { return Recipe::where('title', 'rlike', $this->parentState->search); } }