Files
ahrommag/app/Livewire/CategoryBlog.php
2025-11-16 12:43:07 +03:30

515 lines
21 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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,
]);
}
}