515 lines
21 KiB
PHP
515 lines
21 KiB
PHP
<?php
|
||
|
||
namespace App\Livewire;
|
||
|
||
use App\Models\Blog;
|
||
use App\Models\Category;
|
||
use Illuminate\Support\Str;
|
||
use Livewire\Component;
|
||
use Livewire\WithPagination;
|
||
use Livewire\Attributes\Layout;
|
||
use Illuminate\Support\Facades\URL;
|
||
use Illuminate\Pagination\Paginator;
|
||
|
||
class CategoryBlog extends Component
|
||
{
|
||
use WithPagination;
|
||
|
||
public $slug;
|
||
public $title;
|
||
public $page;
|
||
public $category;
|
||
public $is_news = false;
|
||
public $categories = [];
|
||
public $categoriesNotBlog = [];
|
||
public $blogOrNotBlog;
|
||
|
||
public $parentCategories = [];
|
||
public $childCategories = [];
|
||
public $subChildCategories = [];
|
||
public $selectedCategoryId = null;
|
||
public $selectedTopLevelCategoryId = null;
|
||
public $selectedSecondLevelCategory = null;
|
||
public $topParent = null;
|
||
public $selectedUrl;
|
||
public $allParentsWithChildren;
|
||
public $selectedThirdLevelCategory;
|
||
|
||
|
||
public function mount($slug = null, $page = 1)
|
||
{
|
||
$this->slug = $slug;
|
||
$this->page = $page;
|
||
$this->is_news = request()->is('category/news*');
|
||
|
||
// گرفتن همه دستههای والد (باکس ۱)
|
||
if ($this->is_news) {
|
||
$operation = "!=";
|
||
} else {
|
||
$operation = "=";
|
||
}
|
||
$this->parentCategories = Category::where('parent_id', $operation, null)
|
||
->whereNull('parent_below')
|
||
->where('status', 1)
|
||
->where('is_news', $this->is_news ? 1 : 0)
|
||
->orderBy('title')
|
||
->get();
|
||
|
||
if ($this->slug == 'all') {
|
||
$this->category = [
|
||
"id" => 0,
|
||
"title" => "همه",
|
||
"slug" => "all",
|
||
"is_news" => 0,
|
||
"status" => 1,
|
||
];
|
||
$this->childCategories = collect();
|
||
$this->subChildCategories = collect();
|
||
|
||
// مقداردهی متغیرهای انتخاب شده
|
||
$this->selectedCategoryId = null;
|
||
$this->selectedTopLevelCategoryId = null;
|
||
$this->selectedSecondLevelCategory = null;
|
||
} else {
|
||
$query = Category::query();
|
||
if ($this->is_news) {
|
||
$query->where('is_news', 1);
|
||
} else {
|
||
$query->where('is_news', 0);
|
||
}
|
||
$category = $query->with('parent')->where('slug', $this->slug)->first();
|
||
if (!$category) {
|
||
abort(404, 'دستهبندی مورد نظر یافت نشد');
|
||
}
|
||
|
||
$this->category = $category;
|
||
|
||
// پیدا کردن والد سطح اول (top-level parent) دسته انتخاب شده
|
||
$topParent = $category;
|
||
while ($topParent && ($topParent->parent_id !== null || $topParent->parent_below !== null)) {
|
||
if ($topParent->parent_id !== null) {
|
||
$topParent = Category::find($topParent->parent_id);
|
||
} elseif ($topParent->parent_below !== null) {
|
||
$topParent = Category::find($topParent->parent_below);
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
$this->topParent = $topParent;
|
||
|
||
$this->selectedCategoryId = $category->id; // دسته انتخاب شده (باکس سوم یا خودش)
|
||
$this->selectedTopLevelCategoryId = $topParent ? $topParent->id : null;
|
||
|
||
if (!$this->is_news) {
|
||
// باکس دوم: زیردستههای والد سطح اول
|
||
if ($topParent) {
|
||
$this->childCategories = Category::where(function($query) use ($topParent) {
|
||
$query->where('parent_id', $topParent->id)
|
||
->orWhere('parent_below', $topParent->id);
|
||
})
|
||
->where('status', 1)
|
||
->orderBy('title')
|
||
->get();
|
||
|
||
if ($category->id == $topParent->id) {
|
||
// دسته انتخاب شده، دسته والد سطح اول است (باکس سوم خالی)
|
||
$this->selectedSecondLevelCategory = null;
|
||
$this->subChildCategories = collect();
|
||
} elseif ($this->childCategories->contains('id', $category->id)) {
|
||
// دسته انتخاب شده، یک زیردسته از باکس دوم است
|
||
$this->selectedSecondLevelCategory = $category;
|
||
$this->subChildCategories = Category::where(function($query) use ($category) {
|
||
$query->where('parent_id', $category->id)
|
||
->orWhere('parent_below', $category->id);
|
||
})
|
||
->where('status', 1)
|
||
->orderBy('title')
|
||
->get();
|
||
} else {
|
||
// دسته انتخاب شده، زیردسته ای از باکس سوم است (یا پایینتر)
|
||
// باید والد سطح دوم اون دسته رو پیدا کنیم تا باکس سوم درست نمایش داده بشه
|
||
$secondLevelParent = $category->parent_id ? Category::find($category->parent_id) : Category::find($category->parent_below);
|
||
if ($secondLevelParent) {
|
||
$this->selectedSecondLevelCategory = $secondLevelParent;
|
||
$this->subChildCategories = Category::where(function($query) use ($secondLevelParent) {
|
||
$query->where('parent_id', $secondLevelParent->id)
|
||
->orWhere('parent_below', $secondLevelParent->id);
|
||
})
|
||
->where('status', 1)
|
||
->orderBy('title')
|
||
->get();
|
||
} else {
|
||
$this->selectedSecondLevelCategory = null;
|
||
$this->subChildCategories = collect();
|
||
}
|
||
if ($this->selectedSecondLevelCategory && $category->id != $this->selectedSecondLevelCategory->id) {
|
||
$this->selectedThirdLevelCategory = $category;
|
||
} else {
|
||
$this->selectedThirdLevelCategory = null;
|
||
}
|
||
|
||
}
|
||
} else {
|
||
$this->childCategories = collect();
|
||
$this->subChildCategories = collect();
|
||
$this->selectedSecondLevelCategory = null;
|
||
}
|
||
} else {
|
||
$this->subChildCategories = collect();
|
||
$this->childCategories = collect();
|
||
$this->selectedTopLevelCategoryId = $category->id ?? null;
|
||
}
|
||
}
|
||
|
||
$this->title = $this->category['title'];
|
||
$this->loadCategories();
|
||
//
|
||
// // اگر دسته انتخاب شده والد است (parent_id و parent_below هر دو null)
|
||
// if ($category->parent_id === null && $category->parent_below === null) {
|
||
// // باکس ۲: زیردستههای دسته والد انتخاب شده
|
||
// $this->childCategories = Category::where(function($query) use ($category) {
|
||
// $query->where('parent_id', $category->id)
|
||
// ->orWhere('parent_below', $category->id);
|
||
// })
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
//
|
||
// $this->subChildCategories = collect();
|
||
// } else {
|
||
// // دسته انتخاب شده زیردسته است
|
||
// // باکس ۲: زیردستههای دسته والد آن زیردسته (پیدا کردن دسته والد)
|
||
// $parent = Category::find($category->parent_id ?: $category->parent_below);
|
||
// if ($parent) {
|
||
// $this->childCategories = Category::where(function($query) use ($parent) {
|
||
// $query->where('parent_id', $parent->id)
|
||
// ->orWhere('parent_below', $parent->id);
|
||
// })
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
// } else {
|
||
// $this->childCategories = collect();
|
||
// }
|
||
//
|
||
// // باکس ۳: زیردستههای زیردسته انتخاب شده
|
||
// $this->subChildCategories = Category::where(function($query) use ($category) {
|
||
// $query->where('parent_id', $category->id)
|
||
// ->orWhere('parent_below', $category->id);
|
||
// })
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
// }
|
||
// }
|
||
|
||
// $this->title = $this->category['title'];
|
||
// $this->loadCategories();
|
||
}
|
||
|
||
protected function loadCategories()
|
||
{
|
||
// if ($this->category['slug'] == 'news') {
|
||
//
|
||
// $this->categories = Category::where('is_news', ($this->is_news ? 1 : 0))
|
||
// ->where('parent_id' , '!=' , null)
|
||
// ->whereNull('parent_below')
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
// }elseif($this->category['slug'] == 'all'){
|
||
// $this->categories = Category::where('is_news', ($this->is_news ? 1 : 0))
|
||
// ->whereNull('parent_id')
|
||
// ->whereNull('parent_below')
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
// } else {
|
||
//// $this->categories = collect([$this->category]);
|
||
// if ($this->is_news) {
|
||
// $operation = "!=";
|
||
// } else {
|
||
// $operation = "=";
|
||
// }
|
||
// $this->categories = Category::with('parent')->where('is_news', ($this->is_news ? 1 : 0))
|
||
// ->where('parent_id', $operation, null)
|
||
// ->whereNull('parent_below')
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
//
|
||
// $this->categoriesNotBlog = Category::where(function($query) {
|
||
// $query->where('parent_id', $this->category['id'])
|
||
// ->orWhere('parent_below', $this->category['id']);
|
||
// })
|
||
// ->where('status', 1)
|
||
// ->orderBy('title')
|
||
// ->get();
|
||
// }
|
||
}
|
||
|
||
public function goToCategory($catId, $is_news)
|
||
{
|
||
$this->slug = null;
|
||
if (!$is_news && $catId == 0) {
|
||
$this->slug = 'all';
|
||
} elseif ($is_news && $catId == 0) {
|
||
$this->slug = 'news';
|
||
} else {
|
||
$SSCategory = Category::findOrFail($catId);
|
||
$this->slug = $SSCategory->slug;
|
||
}
|
||
$this->page = 1;
|
||
$this->is_news = $is_news;
|
||
// گرفتن همه دستههای والد (باکس ۱)
|
||
if ($this->is_news) {
|
||
$operation = "!=";
|
||
} else {
|
||
$operation = "=";
|
||
}
|
||
$this->parentCategories = Category::where('parent_id', $operation, null)
|
||
->whereNull('parent_below')
|
||
->where('status', 1)
|
||
->where('is_news', $this->is_news ? 1 : 0)
|
||
->orderBy('title')
|
||
->get();
|
||
|
||
$allParentsWithChildren = Category::where('parent_id', $operation, null)
|
||
->whereNull('parent_below')
|
||
->where('status', 1)
|
||
->where('is_news', $this->is_news ? 1 : 0)
|
||
->orderBy('title')
|
||
->with('childrenRecursive')
|
||
->get();
|
||
|
||
if ($this->slug == 'all') {
|
||
$this->category = collect([
|
||
"id" => 0,
|
||
"title" => "همه",
|
||
"slug" => "all",
|
||
"is_news" => 0,
|
||
"status" => 1,
|
||
]);
|
||
$this->childCategories = collect();
|
||
$this->subChildCategories = collect();
|
||
|
||
// مقداردهی متغیرهای انتخاب شده
|
||
$this->selectedCategoryId = null;
|
||
$this->selectedTopLevelCategoryId = null;
|
||
$this->selectedSecondLevelCategory = null;
|
||
} else {
|
||
$query = Category::query();
|
||
if ($this->is_news) {
|
||
$query->where('is_news', 1);
|
||
} else {
|
||
$query->where('is_news', 0);
|
||
}
|
||
$category = $query->with('parent')->where('slug', $this->slug)->first();
|
||
if (!$category) {
|
||
abort(404, 'دستهبندی مورد نظر یافت نشد');
|
||
}
|
||
|
||
$this->category = $category;
|
||
|
||
// پیدا کردن والد سطح اول (top-level parent) دسته انتخاب شده
|
||
$topParent = $category;
|
||
while ($topParent && ($topParent->parent_id !== null || $topParent->parent_below !== null)) {
|
||
if ($topParent->parent_id !== null) {
|
||
$topParent = Category::find($topParent->parent_id);
|
||
} elseif ($topParent->parent_below !== null) {
|
||
$topParent = Category::find($topParent->parent_below);
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
$this->topParent = $topParent;
|
||
|
||
$this->selectedCategoryId = $category->id; // دسته انتخاب شده (باکس سوم یا خودش)
|
||
$this->selectedTopLevelCategoryId = $topParent ? $topParent->id : null;
|
||
|
||
if (!$this->is_news) {
|
||
// باکس دوم: زیردستههای والد سطح اول
|
||
if ($topParent) {
|
||
$this->childCategories = Category::where(function($query) use ($topParent) {
|
||
$query->where('parent_id', $topParent->id)
|
||
->orWhere('parent_below', $topParent->id);
|
||
})
|
||
->where('status', 1)
|
||
->orderBy('title')
|
||
->get();
|
||
|
||
if ($category->id == $topParent->id) {
|
||
// دسته انتخاب شده، دسته والد سطح اول است (باکس سوم خالی)
|
||
$this->selectedSecondLevelCategory = null;
|
||
$this->subChildCategories = collect();
|
||
} elseif ($this->childCategories->contains('id', $category->id)) {
|
||
// دسته انتخاب شده، یک زیردسته از باکس دوم است
|
||
$this->selectedSecondLevelCategory = $category;
|
||
$this->subChildCategories = Category::where(function($query) use ($category) {
|
||
$query->where('parent_id', $category->id)
|
||
->orWhere('parent_below', $category->id);
|
||
})
|
||
->where('status', 1)
|
||
->orderBy('title')
|
||
->get();
|
||
} else {
|
||
// دسته انتخاب شده، زیردسته ای از باکس سوم است (یا پایینتر)
|
||
// باید والد سطح دوم اون دسته رو پیدا کنیم تا باکس سوم درست نمایش داده بشه
|
||
$secondLevelParent = $category->parent_id ? Category::find($category->parent_id) : Category::find($category->parent_below);
|
||
if ($secondLevelParent) {
|
||
$this->selectedSecondLevelCategory = $secondLevelParent;
|
||
$this->subChildCategories = Category::where(function($query) use ($secondLevelParent) {
|
||
$query->where('parent_id', $secondLevelParent->id)
|
||
->orWhere('parent_below', $secondLevelParent->id);
|
||
})
|
||
->where('status', 1)
|
||
->orderBy('title')
|
||
->get();
|
||
} else {
|
||
$this->selectedSecondLevelCategory = null;
|
||
$this->subChildCategories = collect();
|
||
}
|
||
}
|
||
} else {
|
||
$this->childCategories = collect();
|
||
$this->subChildCategories = collect();
|
||
$this->selectedSecondLevelCategory = null;
|
||
}
|
||
} else {
|
||
$this->subChildCategories = collect();
|
||
$this->childCategories = collect();
|
||
$this->selectedTopLevelCategoryId = $category->id ?? null;
|
||
}
|
||
}
|
||
|
||
$this->title = $this->category['title'];
|
||
$this->loadCategories();
|
||
return true;
|
||
}
|
||
|
||
public function loadCategoriesAndChilds ()
|
||
{
|
||
if ($this->is_news) {
|
||
$operation = "!=";
|
||
} else {
|
||
$operation = "=";
|
||
}
|
||
$allParentsWithChildren = Category::where('parent_id', $operation, null)
|
||
->whereNull('parent_below')
|
||
->where('status', 1)
|
||
->where('is_news', $this->is_news ? 1 : 0)
|
||
->orderBy('title')
|
||
->with('childrenRecursive')
|
||
->get();
|
||
return response()->json($allParentsWithChildren);
|
||
}
|
||
|
||
public function generateSlugAndNavigate($catId, $isNews)
|
||
{
|
||
$slug = null;
|
||
|
||
if (!$isNews && $catId == 0) {
|
||
$slug = 'all';
|
||
} elseif ($isNews && $catId == 0) {
|
||
$slug = 'news';
|
||
} else {
|
||
$category = Category::findOrFail($catId);
|
||
$slug = $category->slug;
|
||
}
|
||
|
||
// Generate the target URL
|
||
$url = $isNews
|
||
? $slug != 'news' ? route('NewsCategory.show', ['slug' => $slug]) . "/" : route('NewsCategory.index').'/'
|
||
: route('CategoryBlog.index', ['slug' => $slug]) . "/";
|
||
|
||
// Emit event to frontend for Livewire navigate
|
||
$this->dispatch('navigate-to', $url);
|
||
return;
|
||
}
|
||
|
||
#[Layout('components.layouts.app')]
|
||
public function render()
|
||
{
|
||
if ($this->page == 1 && str_contains(URL::current(), '/page/1')) {
|
||
if ($this->is_news) {
|
||
return redirect()->route('NewsCategory.index', ['slug' => $this->slug]);
|
||
} else {
|
||
return redirect()->route('CategoryBlog.index', ['slug' => $this->slug]);
|
||
}
|
||
}
|
||
|
||
$categoryIds = [];
|
||
|
||
if ($this->slug == 'all') {
|
||
$this->blogOrNotBlog = 'blog';
|
||
$blogs = Blog::query()
|
||
->where('status', 1)
|
||
->whereNull('notBlog')
|
||
->orderByDesc('published_at')
|
||
->paginate(18, ['*'], 'page', $this->page);
|
||
} else {
|
||
$category = $this->category;
|
||
|
||
if ($category instanceof Category) {
|
||
$categoryIds = $category->getAllDescendantIds();
|
||
$categoryIds[] = $category->id;
|
||
} else {
|
||
$categoryIds = [$category['id']];
|
||
}
|
||
|
||
if ($this->is_news) {
|
||
$this->blogOrNotBlog = 'notblog';
|
||
$blogs = Blog::query()
|
||
->where('status', 1)
|
||
->where('notBlog', 1)
|
||
->where(function ($query) use ($categoryIds) {
|
||
$query->where(function ($q) use ($categoryIds) {
|
||
foreach ($categoryIds as $categoryId) {
|
||
$q->orWhereJsonContains('category_array', (string)$categoryId);
|
||
}
|
||
});
|
||
})
|
||
->orderByDesc('published_at')
|
||
->paginate(18, ['*'], 'page', $this->page);
|
||
} else {
|
||
$this->blogOrNotBlog = 'blog';
|
||
$blogs = Blog::query()
|
||
->where('status', 1)
|
||
->whereNull('notBlog')
|
||
->where(function ($query) use ($categoryIds) {
|
||
$query->where(function ($q) use ($categoryIds) {
|
||
foreach ($categoryIds as $categoryId) {
|
||
$q->orWhereJsonContains('category_array', (string)$categoryId);
|
||
}
|
||
});
|
||
})
|
||
->orderByDesc('published_at')
|
||
->paginate(18, ['*'], 'page', $this->page);
|
||
}
|
||
}
|
||
|
||
if ($this->is_news && isset($this->category['slug']) && $this->category['slug'] == 'news') {
|
||
$this->blogOrNotBlog = 'notblog';
|
||
$blogs = Blog::query()
|
||
->where('status', 1)
|
||
->where('notBlog', 1)
|
||
->orderByDesc('published_at')
|
||
->paginate(18, ['*'], 'page', $this->page);
|
||
}
|
||
|
||
$blogs->setPageName('page');
|
||
if ($this->is_news) {
|
||
$blogs->setPath(route('NewsCategory.index', ['slug' => $this->slug]));
|
||
} else {
|
||
$blogs->setPath(route('CategoryBlog.index', ['slug' => $this->slug]));
|
||
}
|
||
|
||
Paginator::defaultView('custom-pagination');
|
||
|
||
return view('livewire.category-blog', [
|
||
'blogs' => $blogs,
|
||
]);
|
||
}
|
||
|
||
}
|