forked from eatvio/eatvio-infra
99 lines
2.7 KiB
PHP
99 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Recipe;
|
|
|
|
use App\Livewire\Recipe\ListView;
|
|
use App\Models\Recipe;
|
|
use App\Models\Tag;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class ListViewService
|
|
{
|
|
private ListView $parentState;
|
|
|
|
public function __construct(ListView $parent)
|
|
{
|
|
$this->parentState = $parent;
|
|
}
|
|
|
|
public function buildRecipes(): Recipe
|
|
{
|
|
$recipes = $this->getPrimaryCriteriedRecipes();
|
|
|
|
return $this->getSecondaryCriteriedRecipes($recipes);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
});
|
|
}
|
|
}
|