Files
admin/app/Models/Category.php
Husanjonazamov e0f1989655 classify admin
2026-02-24 12:52:01 +05:00

210 lines
5.9 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Support\Facades\Storage;
use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
class Category extends Model
{
use HasFactory, HasRecursiveRelationships;
protected $fillable = [
'name',
'parent_category_id',
'image',
'slug',
'status',
'description',
'is_job_category',
'price_optional',
];
public function getParentKeyName()
{
return 'parent_category_id';
}
protected $appends = ['translated_name', 'translated_description'];
protected $with = ['translations'];
public function subcategories()
{
return $this->hasMany(self::class, 'parent_category_id');
}
public function custom_fields()
{
return $this->hasMany(CustomFieldCategory::class);
}
public function getImageAttribute($image)
{
if (! empty($image)) {
return url(Storage::url($image));
}
return $image;
}
public function items()
{
return $this->hasMany(Item::class);
}
public function approved_items()
{
return $this->hasMany(Item::class)->where('status', 'approved');
}
public function getAllItemsCountAttribute()
{
// Count items in this category
$totalItems = $this->items()->where('status', 'approved')->getNonExpiredItems()->count();
// Count items from ALL descendants (not just loaded ones) using recursive query
$descendantIds = $this->descendants()
->where('status', 1)
->pluck('id')
->toArray();
if (! empty($descendantIds)) {
$descendantItemsCount = Item::without('translations')
->whereIn('category_id', $descendantIds)
->where('status', 'approved')
->getNonExpiredItems()
->count();
$totalItems += $descendantItemsCount;
}
return $totalItems;
}
public function scopeSearch($query, $search)
{
$search = '%'.$search.'%';
return $query->where(function ($q) use ($search) {
$q->orWhere('name', 'LIKE', $search)
->orWhere('description', 'LIKE', $search)
->orWhereHas('translations', function ($q) use ($search) {
$q->where('description', 'LIKE', $search);
});
});
}
public function slider(): MorphOne
{
return $this->morphOne(Slider::class, 'model');
}
public function translations()
{
return $this->hasMany(CategoryTranslation::class);
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (! empty($languageCode)) {
// NOTE : This code can be done in Cache
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (empty($language)) {
return $this->name;
}
$languageId = $language->id;
$translation = $this->translations->first(static function ($data) use ($languageId) {
return $data->language_id == $languageId;
});
return ! empty($translation?->name) ? $translation->name : $this->name;
}
return $this->name;
}
public function getTranslatedDescriptionAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (! empty($languageCode)) {
// NOTE : This code can be done in Cache
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (empty($language)) {
return $this->description;
}
$languageId = $language->id;
$translation = $this->translations->first(static function ($data) use ($languageId) {
return $data->language_id == $languageId;
});
return ! empty($translation?->description) ? $translation->description : $this->description;
}
return $this->description;
}
public function parent()
{
return $this->belongsTo(Category::class, 'parent_category_id');
}
public function getFullPathAttribute()
{
$names = [];
$current = $this;
$visited = [];
while ($current) {
if (in_array($current->id, $visited, true)) {
break; // prevent loop
}
$visited[] = $current->id;
$names[] = $current->name;
$current = $current->parent;
}
return implode(' > ', array_reverse($names));
}
public function getItemsGroupedByStatusAttribute()
{
$counts = [];
// Count items in this category
$items = $this->items()->get();
foreach ($items as $item) {
$counts[$item->status] = ($counts[$item->status] ?? 0) + 1;
}
// Include subcategories recursively
foreach ($this->subcategories as $subcategory) {
$subCounts = $subcategory->items_grouped_by_status;
foreach ($subCounts as $status => $count) {
$counts[$status] = ($counts[$status] ?? 0) + $count;
}
}
return $counts;
}
public function getOtherItemsCountAttribute()
{
$totalItems = $this->items()->where('status', '!=', 'approved')->count();
foreach ($this->subcategories as $subcategory) {
$totalItems += $subcategory->other_items_count;
}
return $totalItems;
}
}