classify admin

This commit is contained in:
Husanjonazamov
2026-02-24 12:52:01 +05:00
commit e0f1989655
769 changed files with 1263008 additions and 0 deletions

94
app/Models/Area.php Normal file
View File

@@ -0,0 +1,94 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Area extends Model {
use HasFactory;
protected $fillable = [
'name',
'country_id',
'state_id',
'city_id',
'state_code',
'latitude',
'longitude'
];
protected $appends = ['translated_name'];
protected $with = ['translations'];
public function city() {
return $this->belongsTo(City::class);
}
public function state() {
return $this->belongsTo(State::class);
}
public function country() {
return $this->belongsTo(Country::class);
}
public function translations()
{
return $this->hasMany(AreaTranslation::class);
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
if ($column == "city.name") {
$query->whereHas('city', function ($query) use ($value) {
$query->where('city_id', $value);
});
} elseif ($column == "state.name") {
$query->whereHas('state', function ($query) use ($value) {
$query->where('state_id', $value);
});
} elseif ($column == "country.name") {
$query->whereHas('country', function ($query) use ($value) {
$query->where('country_id', $value);
});
} else {
$query->where((string)$column, (string)$value);
}
}
}
return $query;
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('id', 'LIKE', $search)
->orWhere('name', 'LIKE', $search)
->orWhere('city_id', 'LIKE', $search)
->orWhere('state_id', 'LIKE', $search)
->orWhere('state_code', 'LIKE', $search)
->orWhere('country_id', 'LIKE', $search)
->orWhereHas('country', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('state', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('city', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
return $query;
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translations = $this->relationLoaded('translations') ? $this->translations : $this->translations()->get();
$translation = $translations->firstWhere('language_id', $language->id);
return $translation?->name ?? $this->name;
}
return $this->name;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AreaTranslation extends Model
{
use HasFactory;
protected $fillable = ['area_id', 'language_id', 'name'];
public function area()
{
return $this->belongsTo(Area::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

15
app/Models/BlockUser.php Normal file
View File

@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class BlockUser extends Model {
use HasFactory;
protected $fillable = [
'user_id',
'blocked_user_id'
];
}

137
app/Models/Blog.php Normal file
View File

@@ -0,0 +1,137 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Blog extends Model {
use HasFactory;
protected $dates = ['created_at', 'updated_at'];
protected $fillable = [
'title',
'slug',
'description',
'image',
'tags'
];
protected $appends = ['translated_title', 'translated_description', 'translated_tags'];
public function category() {
return $this->belongsTo(Category::class, 'category_id');
}
public function getImageAttribute($image) {
if (!empty($image)) {
return url(Storage::url($image));
}
return $image;
}
public function getTagsAttribute($value) {
if (is_array($value)) {
return $value;
}
if (is_string($value)) {
return explode(',', $value);
}
return [];
}
public function setTagsAttribute($value) {
if (is_array($value)) {
$cleaned = array_map(fn($tag) => trim($tag, " \t\n\r\0\x0B\"'"), $value);
$this->attributes['tags'] = implode(',', $cleaned);
} elseif (is_string($value)) {
$this->attributes['tags'] = trim($value, " \t\n\r\0\x0B\"'");
} else {
$this->attributes['tags'] = '';
}
}
public function translations() {
return $this->hasMany(BlogTranslation::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('title', 'LIKE', $search)
->orWhere('description', 'LIKE', $search)
->orWhere('tags', 'LIKE', $search);
});
return $query;
}
public function scopeSort($query, $column, $order) {
if ($column == "category_name") {
return $query->leftJoin('categories', 'categories.id', '=', 'blogs.category_id')
->orderBy('categories.name', $order)
->select('blogs.*');
}
return $query->orderBy($column, $order);
}
public function getTranslatedTitleAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->title) ? $translation->title : $this->title;
}
return $this->title;
}
public function getTranslatedTagsAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
if (!empty($translation?->tags)) {
if (is_array($translation->tags)) {
return array_map(fn($tag) => trim($tag, " \t\n\r\0\x0B\"'"), $translation->tags);
}
if (is_string($translation->tags)) {
return array_map(fn($tag) => trim($tag, " \t\n\r\0\x0B\"'"), explode(',', $translation->tags));
}
}
}
return array_map(fn($tag) => trim($tag, " \t\n\r\0\x0B\"'"), $this->tags ?? []);
}
public function getTranslatedDescriptionAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->description) ? $translation->description : $this->description;
}
return $this->description;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class BlogTranslation extends Model
{
use HasFactory;
protected $fillable = ['blog_id', 'language_id', 'title', 'description', 'tags'];
public function blog()
{
return $this->belongsTo(Blog::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
public function getTagsAttribute($value)
{
if (is_array($value)) {
return $value;
}
if (!empty($value)) {
return explode(',', $value);
}
return [];
}
public function setTagsAttribute($value) {
if (is_array($value)) {
$cleaned = array_map(fn($tag) => trim($tag, " \t\n\r\0\x0B\"'"), $value);
$this->attributes['tags'] = implode(',', $cleaned);
} elseif (is_string($value)) {
$this->attributes['tags'] = trim($value, " \t\n\r\0\x0B\"'");
} else {
$this->attributes['tags'] = '';
}
}
}

209
app/Models/Category.php Normal file
View File

@@ -0,0 +1,209 @@
<?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;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CategoryTranslation extends Model {
protected $fillable = [
'name',
'description',
'language_id',
'category_id'
];
public function language() {
return $this->belongsTo(Language::class);
}
public function category() {
return $this->belongsTo(Category::class);
}
}

56
app/Models/Chat.php Normal file
View File

@@ -0,0 +1,56 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Chat extends Model {
use HasFactory;
protected $fillable = [
'sender_id',
'item_offer_id',
'message',
'file',
'audio',
'is_read'
];
protected $appends = ['message_type'];
public function sender() {
return $this->belongsTo(User::class, 'sender_id');
}
public function getFileAttribute($file) {
if (!empty($file)) {
return url(Storage::url($file));
}
return $file;
}
public function getAudioAttribute($value) {
if (!empty($value)) {
return url(Storage::url($value));
}
return $value;
}
public function getMessageTypeAttribute() {
if (!empty($this->audio)) {
return "audio";
}
if (!empty($this->file) && $this->message == "") {
return "file";
}
if (!empty($this->file) && $this->message != "") {
return "file_and_text";
}
return "text";
}
}

111
app/Models/City.php Normal file
View File

@@ -0,0 +1,111 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class City extends Model {
use HasFactory;
protected $fillable = [
"id",
"name",
"state_id",
"state_code",
"country_id",
"country_code",
"latitude",
"longitude",
"created_at",
"updated_at",
"flag",
"wikiDataId",
];
protected $appends = ['translated_name'];
protected $with = ['translations'];
public function state() {
return $this->belongsTo(State::class);
}
public function country() {
return $this->belongsTo(Country::class);
}
public function translations()
{
return $this->hasMany(CityTranslation::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('cities.id', 'LIKE', $search)
->orWhere('cities.name', 'LIKE', $search)
->orWhere('cities.state_id', 'LIKE', $search)
->orWhere('cities.state_code', 'LIKE', $search)
->orWhere('cities.country_id', 'LIKE', $search)
->orWhere('cities.country_code', 'LIKE', $search)
->orWhereHas('state', function ($q) use ($search) {
$q->where('states.name', 'LIKE', $search);
})
->orWhereHas('country', function ($q) use ($search) {
$q->where('countries.name', 'LIKE', $search);
});
});
return $query;
}
public function scopeSort($query, $column, $order) {
if ($column == "country_name") {
$query = $query->leftJoin('countries', 'countries.id', '=', 'cities.country_id')
->orderBy('countries.name', $order);
} elseif ($column == "state_name") {
$query = $query->leftJoin('states', 'states.id', '=', 'cities.state_id')
->orderBy('states.name', $order);
} else {
$query = $query->orderBy("cities.$column", $order);
}
return $query->select('cities.*');
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
if($column == "state_name") {
$query->whereHas('state', function ($query) use ($value) {
$query->where('state_id', $value);
});
}
elseif($column == "country_name") {
$query->whereHas('country', function ($query) use ($value) {
$query->where('country_id', $value);
});
}
else {
$query->where((string)$column, (string)$value);
}
}
}
return $query;
}
public function areas(): HasMany
{
return $this->hasMany(Area::class);
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translations = $this->relationLoaded('translations') ? $this->translations : $this->translations()->get();
$translation = $translations->firstWhere('language_id', $language->id);
return $translation?->name ?? $this->name;
}
return $this->name;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CityTranslation extends Model
{
use HasFactory;
protected $fillable = ['city_id', 'language_id', 'name'];
public function city()
{
return $this->belongsTo(City::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

25
app/Models/ContactUs.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ContactUs extends Model
{
use HasFactory;
protected $table = 'contact_us';
protected $fillable = [
'name',
'email',
'phone',
'subject',
'message'
];
public function scopeSort($query, $column, $order) {
$query = $query->orderBy($column, $order);
return $query->select('contact_us.*');
}
}

102
app/Models/Country.php Normal file
View File

@@ -0,0 +1,102 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
use HasFactory;
protected $fillable = [
'id',
'name',
'iso3',
'numeric_code',
'iso2',
'phonecode',
'capital',
'currency',
'currency_name',
'currency_symbol',
'tld',
'native',
'region',
'region_id',
'subregion',
'subregion_id',
'nationality',
'timezones',
'translations',
'latitude',
'longitude',
'emoji',
'emojiU',
'created_at',
'updated_at',
'flag',
'wikiDataId',
];
protected $appends = ['translated_name'];
protected $with = ['nameTranslations'];
public function scopeSearch($query, $search)
{
$search = '%'.$search.'%';
$query = $query->where(function ($q) use ($search) {
$q->orWhere('id', 'LIKE', $search)
->orWhere('name', 'LIKE', $search)
->orWhere('numeric_code', 'LIKE', $search)
->orWhere('phonecode', 'LIKE', $search);
});
return $query;
}
public function states()
{
return $this->hasMany(State::class);
}
public function nameTranslations()
{
return $this->hasMany(CountryTranslation::class);
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (empty($languageCode)) {
return $this->name;
}
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (! $language) {
return $this->name;
}
$nameTranslations = $this->relationLoaded('nameTranslations')
? $this->nameTranslations
: $this->nameTranslations()->get();
$translation = $nameTranslations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return ! empty($translation?->name) ? $translation->name : $this->name;
}
// public function translations()
// {
// return $this->hasMany(CountryTranslation::class);
// }
public function currency()
{
return $this->hasOne(Currency::class);
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CountryTranslation extends Model
{
use HasFactory;
protected $fillable = ['country_id', 'language_id', 'name'];
public function country()
{
return $this->belongsTo(Country::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

79
app/Models/Currency.php Normal file
View File

@@ -0,0 +1,79 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Currency extends Model
{
use HasFactory;
protected $fillable = [
'iso_code',
'name',
'symbol',
'symbol_position',
'decimal_places',
'thousand_separator',
'decimal_separator',
'country_id',
];
public function country()
{
return $this->belongsTo(Country::class, 'country_id', 'id');
}
public function scopeSort($query, $sortBy, $order)
{
if ($sortBy === 'country_name' || $sortBy === 'country.name') {
return $query
->leftJoin('countries', 'currencies.country_id', '=', 'countries.id')
->orderBy('countries.name', $order)
->select('currencies.*');
}
return $query->orderBy($sortBy, $order);
}
// protected $appends = ['translated_name'];
// public function translations()
// {
// return $this->hasMany(CurrencyTranslation::class);
// }
public function scopeSearch($query, $search)
{
$search = '%' . $search . '%';
return $query->where(function ($q) use ($search) {
$q->where('currencies.id', 'LIKE', $search)
->orWhere('currencies.iso_code', 'LIKE', $search)
->orWhere('currencies.name', 'LIKE', $search)
->orWhere('currencies.symbol', 'LIKE', $search)
->orWhereHas('country', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
}
// public function getTranslatedNameAttribute()
// {
// $languageCode = request()->header('Content-Language') ?? app()->getLocale();
// if ($languageCode) {
// $translations = $this->relationLoaded('translations') ? $this->translations : $this->translations()->get();
// $translation = $translations->firstWhere('language_id', $languageCode);
// return $translation?->name ?? $this->name;
// }
// return $this->name;
// }
}

123
app/Models/CustomField.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Throwable;
class CustomField extends Model {
use HasFactory;
protected $fillable = [
'name',
'type',
'image',
'required',
'status',
'values',
'min_length',
'max_length',
];
protected $hidden = ['created_at', 'updated_at'];
protected $appends = ['translated_name', 'translated_value'];
public function custom_field_category() {
return $this->hasMany(CustomFieldCategory::class, 'custom_field_id');
}
public function translations() {
return $this->hasMany(CustomFieldsTranslation::class);
}
public function item_custom_field_values() {
return $this->hasMany(ItemCustomFieldValue::class);
}
public function categories() {
return $this->belongsToMany(Category::class, CustomFieldCategory::class);
}
public function getValuesAttribute($value) {
try {
return array_values(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
} catch (Throwable) {
return $value;
}
}
public function getImageAttribute($image) {
if (!empty($image)) {
return url(Storage::url($image));
}
return $image;
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('name', 'LIKE', $search)
->orWhere('type', 'LIKE', $search)
->orWhere('values', 'LIKE', $search)
->orWhere('status', 'LIKE', $search)
->orWhereHas('categories', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
return $query;
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
if ($column == "category_names") {
$query->whereHas('custom_field_category', function ($query) use ($value) {
$query->where('category_id', $value);
});
} elseif ($column == "type") {
$query->where('type', $value);
} else {
$query->where((string)$column, (string)$value);
}
}
}
return $query;
}
public function getTranslatedNameAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if ($this->relationLoaded('translations')) {
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return $translation->name ?? $this->name;
}
}
return $this->name;
}
public function getTranslatedValueAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if ($this->relationLoaded('translations')) {
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translation = $this->translations->first(fn($t) => $t->language_id == $language->id);
try {
return $translation && $translation->value
? $translation->value
: $this->values;
} catch (\Throwable) {
return $this->values;
}
}
}
return $this->values;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* @method static upsert(null[] $array, array $customFieldCategory)
*/
class CustomFieldCategory extends Model {
use HasFactory;
protected $hidden = ['created_at', 'updated_at'];
protected $fillable = [
'category_id',
'custom_field_id'
];
public function custom_fields() {
return $this->hasOne(CustomField::class, 'id', 'custom_field_id');
}
public function category() {
return $this->hasOne(Category::class);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Throwable;
class CustomFieldsTranslation extends Model
{
use HasFactory;
protected $table = 'custom_fields_translations';
protected $fillable = [
'custom_field_id',
'language_id',
'name',
'value',
];
/**
* Get the custom field that owns this translation.
*/
public function customField()
{
return $this->belongsTo(CustomField::class);
}
/**
* Get the language for this translation.
*/
public function language()
{
return $this->belongsTo(Language::class);
}
public function getValueAttribute($value) {
try {
return array_values(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
} catch (Throwable) {
return $value;
}
}
}

74
app/Models/Faq.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Faq extends Model
{
use HasFactory;
protected $fillable=[
'question',
'answer'
];
protected $appends = ['translated_question','translated_answer'];
public function translations()
{
return $this->hasMany(FaqTranslation::class);
}
public function getTranslation($languageId)
{
return $this->translations->where('language_id', $languageId)->first();
}
public function getTranslatedQuestionAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (empty($languageCode)) {
return $this->question;
}
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (!$language) {
return $this->question;
}
$translations = $this->relationLoaded('translations')
? $this->translations
: $this->translations()->get();
$translation = $translations->first(function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->question) ? $translation->question : $this->question;
}
public function getTranslatedAnswerAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (empty($languageCode)) {
return $this->answer;
}
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (!$language) {
return $this->answer;
}
$translations = $this->relationLoaded('translations')
? $this->translations
: $this->translations()->get();
$translation = $translations->first(function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->answer) ? $translation->answer : $this->answer;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class FaqTranslation extends Model
{
use HasFactory;
protected $fillable = ['faq_id', 'language_id', 'question', 'answer'];
public function faq()
{
return $this->belongsTo(Faq::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

11
app/Models/Favourite.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Favourite extends Model
{
use HasFactory;
}

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class FeatureSection extends Model {
use HasFactory;
protected $fillable = [
'title',
'slug',
'sequence',
'filter',
'value',
'style',
'min_price',
'max_price',
'description'
];
protected $appends = ['translated_name', 'translated_description'];
public function category() {
return $this->belongsTo(Category::class, 'category_id', 'id');
}
public function translations()
{
return $this->hasMany(FeatureSectionTranslation::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('title', 'LIKE', $search)
->orWhere('sequence', 'LIKE', $search)
->orWhere('filter', 'LIKE', $search)
->orWhere('value', 'LIKE', $search)
->orWhere('style', 'LIKE', $search)
->orWhere('min_price', 'LIKE', $search)
->orWhere('max_price', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search)
->orWhere('description', 'LIKE', $search);
});
return $query;
}
public function getTranslatedNameAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
// NOTE : This code can be done in Cache
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (!$language) {
$defaultLanguageCode = Setting::where('name', "default_language")->value('value');
$language = Language::where('code', $defaultLanguageCode)->first();
}
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->name) ? $translation->name : $this->title;
}
return $this->name;
}
public function getTranslatedDescriptionAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (!$language) {
$defaultLanguageCode = Setting::where('name', "default_language")->value('value');
$language = Language::where('code', $defaultLanguageCode)->first();
}
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->description) ? $translation->description : $this->description;
}
return $this->description;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class FeatureSectionTranslation extends Model
{
use HasFactory;
protected $fillable = ['feature_section_id', 'language_id', 'name', 'description'];
public function featureSection()
{
return $this->belongsTo(FeatureSection::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class FeaturedItems extends Model {
use HasFactory;
protected $fillable = [
'start_date',
'end_date',
'item_id',
'package_id',
'user_purchased_package_id',
];
public function user() {
return $this->belongsTo(User::class);
}
public function scopeOnlyActive($query) {
return $query->whereDate('start_date', '<=', date('Y-m-d'))->where(function ($q) {
$q->whereDate('end_date', '>=', date('Y-m-d'))->orWhereNull('end_date');
});
}
public function getImageAttribute($image) {
if (!empty($image)) {
return url(Storage::url($image));
}
return $image;
}
public function item()
{
return $this->belongsTo(Item::class);
}
}

370
app/Models/Item.php Normal file
View File

@@ -0,0 +1,370 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class Item extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = [
'category_id',
'currency_id',
'name',
'price',
'description',
'latitude',
'longitude',
'address',
'contact',
'show_only_to_premium',
'video_link',
'status',
'rejected_reason',
'user_id',
'image',
'country',
'state',
'city',
'area_id',
'all_category_ids',
'slug',
'sold_to',
'expiry_date',
'min_salary',
'max_salary',
'is_edited_by_admin',
'admin_edit_reason',
'package_id',
'region_code',
'created_at',
];
protected $appends = ['translated_name', 'translated_description'];
protected $with = ['translations'];
// Relationships
public function user()
{
return $this->belongsTo(User::class);
}
public function countryRelation()
{
return $this->belongsTo(Country::class);
}
public function currency()
{
return $this->belongsTo(Currency::class, 'currency_id');
}
public function category()
{
return $this->hasOne(Category::class, 'id', 'category_id');
}
public function gallery_images()
{
return $this->hasMany(ItemImages::class);
}
public function custom_fields()
{
return $this->hasManyThrough(
CustomField::class, CustomFieldCategory::class,
'category_id', 'id', 'category_id', 'custom_field_id'
);
}
public function item_custom_field_values()
{
return $this->hasMany(ItemCustomFieldValue::class, 'item_id');
}
public function featured_items()
{
return $this->hasMany(FeaturedItems::class)->onlyActive();
}
public function favourites()
{
return $this->hasMany(Favourite::class);
}
public function item_offers()
{
return $this->hasMany(ItemOffer::class);
}
public function user_reports()
{
return $this->hasMany(UserReports::class);
}
public function sliders(): MorphMany
{
return $this->morphMany(Slider::class, 'model');
}
public function area()
{
return $this->belongsTo(Area::class);
}
public function review()
{
return $this->hasMany(SellerRating::class);
}
public function job_applications()
{
return $this->hasMany(JobApplication::class);
}
// Accessors
public function getImageAttribute($image)
{
return ! empty($image) ? url(Storage::url($image)) : $image;
}
public function getStatusAttribute($value)
{
if ($this->deleted_at) {
return 'inactive';
}
if ($this->expiry_date && $this->expiry_date < Carbon::now()) {
return 'expired';
}
return $value;
}
public function translations()
{
return $this->hasMany(ItemTranslation::class);
}
// Scopes
public function scopeSearch($query, $search)
{
$search = '%'.$search.'%';
return $query->where(function ($q) use ($search) {
$q->orWhere('name', 'LIKE', $search)
->orWhere('description', 'LIKE', $search)
->orWhere('price', 'LIKE', $search)
->orWhere('image', 'LIKE', $search)
->orWhere('latitude', 'LIKE', $search)
->orWhere('longitude', 'LIKE', $search)
->orWhere('address', 'LIKE', $search)
->orWhere('contact', 'LIKE', $search)
->orWhere('show_only_to_premium', 'LIKE', $search)
->orWhere('status', 'LIKE', $search)
->orWhere('video_link', 'LIKE', $search)
->orWhere('clicks', 'LIKE', $search)
->orWhere('user_id', 'LIKE', $search)
->orWhere('country', 'LIKE', $search)
->orWhere('state', 'LIKE', $search)
->orWhere('city', 'LIKE', $search)
->orWhere('category_id', 'LIKE', $search)
->orWhereHas('category', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('user', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('translations', function ($q) use ($search) {
$q->where('name', 'LIKE', $search)
->orWhere('description', 'LIKE', $search)
->orWhere('address', 'LIKE', $search)
->orWhere('city', 'LIKE', $search)
->orWhere('state', 'LIKE', $search)
->orWhere('country', 'LIKE', $search);
});
});
}
public function scopeOwner($query)
{
if (Auth::user()->hasRole('User')) {
return $query->where('user_id', Auth::user()->id);
}
return $query;
}
public function scopeApproved($query)
{
return $query->where('status', 'approved');
}
public function scopeNotOwner($query)
{
return $query->where('user_id', '!=', Auth::user()->id);
}
public function scopeSort($query, $column, $order)
{
if ($column == 'user_name') {
return $query->leftJoin('users', 'users.id', '=', 'items.user_id')
->orderBy('users.name', $order)
->select('items.*');
}
return $query->orderBy($column, $order);
}
public function scopeFilter($query, $filterObject)
{
if (empty($filterObject)) {
return $query;
}
foreach ($filterObject as $column => $value) {
if ($column === 'category_id') {
$categoryId = (int) $value;
$isParentCategory = Category::where('id', $categoryId)
->whereNull('parent_category_id')
->exists();
if ($isParentCategory) {
$childCategoryIds = Category::where('parent_category_id', $categoryId)
->pluck('id')
->toArray();
$allCategoryIds = array_merge([$categoryId], $childCategoryIds);
$query->where(function ($q) use ($allCategoryIds) {
foreach ($allCategoryIds as $catId) {
$q->orWhereRaw('FIND_IN_SET(?, all_category_ids)', [$catId]);
}
});
} else {
$query->where('category_id', $categoryId);
}
continue; // Skip to next filter
}
if ($column == 'status') {
if ($value == 'inactive') {
$query->whereNotNull('deleted_at')
->where(function ($q) {
$q->whereNull('expiry_date')
->orWhere('expiry_date', '>=', Carbon::now());
});
} elseif ($value == 'expired') {
$query->whereNotNull('expiry_date')
->where('expiry_date', '<', Carbon::now())
->whereNull('deleted_at');
} else {
if (in_array($value, [
'review', 'approved', 'rejected',
'sold out', 'soft rejected',
'permanent rejected', 'resubmitted',
])) {
$query->whereNull('deleted_at')
->where(function ($q) {
$q->whereNull('expiry_date')
->orWhere('expiry_date', '>=', Carbon::now());
});
}
$query->where($column, $value);
}
} elseif ($column == 'featured_status') {
if ($value == 'featured') {
$query->whereHas('featured_items');
} elseif ($value == 'premium') {
$query->whereDoesntHave('featured_items');
}
} elseif (in_array($column, ['country', 'state', 'city'])) {
$query->where($column, 'LIKE', '%'.$value.'%');
} else {
$query->where((string) $column, (string) $value);
}
}
return $query;
}
public function scopeOnlyNonBlockedUsers($query)
{
$blocked_user_ids = BlockUser::where('user_id', Auth::user()->id)
->pluck('blocked_user_id');
return $query->whereNotIn('user_id', $blocked_user_ids);
}
public function scopeGetNonExpiredItems($query)
{
return $query->where(function ($query) {
$query->where('expiry_date', '>', Carbon::now())->orWhereNull('expiry_date');
});
}
public function scopeIsJobCategory($query, $isJob = 1)
{
return $query->whereHas('category', function ($q) use ($isJob) {
$q->where('is_job_category', $isJob);
});
}
public function scopePriceOptional($query, $isJob = 1)
{
return $query->whereHas('category', function ($q) use ($isJob) {
$q->where('price_optional', $isJob);
});
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translations = $this->relationLoaded('translations') ? $this->translations : $this->translations()->get();
$translation = $translations->firstWhere('language_id', $language->id);
return $translation?->name ?? $this->name;
}
return $this->name;
}
public function getTranslatedDescriptionAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translations = $this->relationLoaded('translations') ? $this->translations : $this->translations()->get();
$translation = $translations->firstWhere('language_id', $language->id);
return $translation?->description ?? $this->description;
}
return $this->description;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use JsonException;
/**
* @method static create(array $itemCustomFieldValues)
* @method static insert(array $itemCustomFieldValues)
*/
class ItemCustomFieldValue extends Model {
use HasFactory;
protected $fillable = [
'item_id',
'custom_field_id',
'value',
'language_id'
];
public function custom_field() {
return $this->belongsTo(CustomField::class);
}
public function item()
{
return $this->belongsTo(Item::class, 'item_id');
}
public function getValueAttribute($value) {
try {
return array_values(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
} catch (JsonException) {
return $value;
}
}
}

23
app/Models/ItemImages.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class ItemImages extends Model {
use HasFactory;
protected $fillable = [
'item_id',
'image',
];
public function getImageAttribute($image) {
if (!empty($image)) {
return url(Storage::url($image));
}
return $image;
}
}

159
app/Models/ItemOffer.php Normal file
View File

@@ -0,0 +1,159 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class ItemOffer extends Model
{
use HasFactory;
protected $fillable = [
'item_id',
'seller_id',
'buyer_id',
'amount',
];
// protected $appends = [
// 'formatted_amount',
// 'formatted_price',
// 'currency_symbol',
// 'currency_position',
// 'formatted_min_salary',
// 'formatted_max_salary',
// 'formatted_salary_range',
// ];
public function item()
{
return $this->belongsTo(Item::class)->withTrashed();
}
public function seller()
{
return $this->belongsTo(User::class);
}
public function buyer()
{
return $this->belongsTo(User::class);
}
public function chat()
{
return $this->hasMany(Chat::class, 'item_offer_id');
}
// public function scopeOwner($query)
// {
// return $query->where('seller_id', Auth::user()->id)->orWhere('buyer_id', Auth::user()->id);
// }
public function scopeOwner($query)
{
return $query->where(function ($q) {
$q->where('seller_id', Auth::id())
->orWhere('buyer_id', Auth::id());
});
}
// public function getFormattedAmountAttribute()
// {
// if (! $this->amount) {
// return null;
// }
// $item = $this->relationLoaded('item')
// ? $this->item
// : $this->item()->with('countryRelation.currency')->first();
// $symbol = $item?->currency_symbol ?? '₹';
// $position = $item?->currency_position ?? 'left';
// $formatted = number_format($this->amount);
// return $position === 'right'
// ? "{$formatted} {$symbol}"
// : "{$symbol} {$formatted}";
// }
// public function getFormattedPriceAttribute()
// {
// if (! $this->price) {
// return null;
// }
// $symbol = $this->currency_symbol ?? '₹';
// $position = $this->currency_position ?? 'left';
// $formatted = number_format($this->price);
// return $position === 'right'
// ? "{$formatted} {$symbol}"
// : "{$symbol} {$formatted}";
// }
// public function getCurrencySymbolAttribute()
// {
// return $this->countryRelation?->currency?->symbol ?? '₹';
// dd($this->countryRelation);
// }
// public function getCurrencyPositionAttribute()
// {
// return $this->countryRelation?->currency?->symbol_position ?? 'left';
// }
// public function getFormattedMinSalaryAttribute()
// {
// if (! $this->min_salary) {
// return null;
// }
// $symbol = $this->currency_symbol;
// $position = $this->currency_position;
// $formatted = number_format($this->min_salary);
// return $position === 'right'
// ? "{$formatted} {$symbol}"
// : "{$symbol} {$formatted}";
// }
// public function getFormattedMaxSalaryAttribute()
// {
// if (! $this->max_salary) {
// return null;
// }
// $symbol = $this->currency_symbol;
// $position = $this->currency_position;
// $formatted = number_format($this->max_salary);
// return $position === 'right'
// ? "{$formatted} {$symbol}"
// : "{$symbol} {$formatted}";
// }
// public function getFormattedSalaryRangeAttribute()
// {
// if (! $this->min_salary && ! $this->max_salary) {
// return null;
// }
// if ($this->min_salary && ! $this->max_salary) {
// return "From {$this->formatted_min_salary}";
// }
// if (! $this->min_salary && $this->max_salary) {
// return "Upto {$this->formatted_max_salary}";
// }
// if ($this->min_salary && $this->max_salary) {
// return "{$this->formatted_min_salary} - {$this->formatted_max_salary}";
// }
// return $this->formatted_min_salary ?? $this->formatted_max_salary;
// }
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ItemTranslation extends Model
{
use HasFactory;
protected $fillable = [
'item_id',
'language_id',
'name',
'slug',
'description',
'address',
'rejected_reason',
'admin_edit_reason',
];
public function item()
{
return $this->belongsTo(Item::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class JobApplication extends Model
{
use HasFactory;
protected $fillable = [
'item_id',
'user_id',
'recruiter_id',
'full_name',
'email',
'mobile',
'resume',
'status',
];
public function item()
{
return $this->belongsTo(Item::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function recruiter()
{
return $this->belongsTo(User::class);
}
public function getResumeAttribute($image) {
if (!empty($image)) {
return url(Storage::url($image));
}
return $image;
}
}

42
app/Models/Language.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Language extends Model
{
use HasFactory;
protected $fillable = [
'name',
'name_in_english',
'code',
'app_file',
'panel_file',
'web_file',
'rtl',
'image',
'country_code',
];
public function getRtlAttribute($rtl)
{
return $rtl != 0;
}
public function getImageAttribute($value)
{
if (! empty($value)) {
if ($this->code == 'en') {
return asset('/assets/images/'.$value);
}
return url(Storage::url($value));
}
return '';
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Notifications extends Model {
use HasFactory;
protected $fillable = [
'title',
'message',
'image',
'item_id',
'user_id',
'send_to'
];
protected $hidden = [
'updated_at',
'deleted_at'
];
public function getImageAttribute($value) {
if (!empty($value)) {
return url(Storage::url($value));
}
return "";
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('title', 'LIKE', $search)
->orWhere('message', 'LIKE', $search)
->orWhere('send_to', 'LIKE', $search)
->orWhere('item_id', 'LIKE', $search)
->orWhere('user_id', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search);
});
return $query;
}
public function item()
{
return $this->belongsTo(Item::class, 'item_id', 'id');
}
}

27
app/Models/NumberOtp.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class NumberOtp extends Model
{
use HasFactory;
protected $table = 'number_otps';
protected $fillable = [
'number',
'otp',
'expire_at',
'attempts'
];
public function setOtpAttribute($value) {
$this->attributes['otp'] = base64_encode($value);
}
public function getOtpAttribute($value) {
return base64_decode($value);
}
}

191
app/Models/Package.php Normal file
View File

@@ -0,0 +1,191 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class Package extends Model {
use HasFactory;
protected $fillable = [
'name',
'price',
'discount_in_percentage',
'final_price',
'duration',
'item_limit',
'type',
'icon',
'description',
'status',
'ios_product_id',
'is_global',
'key_points',
'listing_duration_type',
'listing_duration_days'
];
protected $appends = ['translated_name', 'translated_description','translated_key_points'];
/**
* Get listing duration type, fallback to package duration if null
*
* @return string|null
*/
public function getListingDurationTypeAttribute($value)
{
// If listing_duration_type is null, return 'package' to indicate it uses package duration
if ($value === null) {
return 'package';
}
return $value;
}
/**
* Get listing duration days, fallback to package duration if null and type is package
*
* @return int|string|null
*/
public function getListingDurationDaysAttribute($value)
{
// If listing_duration_days is null and listing_duration_type is null or 'package', use package duration
if ($value === null || $value === '') {
$listingDurationType = $this->attributes['listing_duration_type'] ?? null;
if ($listingDurationType === null || $listingDurationType === '' || $listingDurationType === 'package') {
// Use raw duration attribute to avoid infinite loop
return $this->attributes['duration'] ?? null;
}
}
return $value;
}
public function user_purchased_packages() {
return $this->hasMany(UserPurchasedPackage::class);
}
public function translations()
{
return $this->hasMany(PackageTranslation::class);
}
public function categories()
{
return $this->belongsToMany(Category::class, 'package_categories', 'package_id', 'category_id');
}
public function package_categories()
{
return $this->hasMany(PackageCategory::class);
}
public function getIconAttribute($icon) {
if (!empty($icon)) {
return url(Storage::url($icon));
}
return $icon;
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('name', 'LIKE', $search)
->orWhere('price', 'LIKE', $search)
->orWhere('discount_in_percentage', 'LIKE', $search)
->orWhere('final_price', 'LIKE', $search)
->orWhere('duration', 'LIKE', $search)
->orWhere('item_limit', 'LIKE', $search)
->orWhere('type', 'LIKE', $search)
->orWhere('description', 'LIKE', $search)
->orWhere('status', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search);
});
return $query;
}
public function getTranslatedNameAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
// NOTE : This code can be done in Cache
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->name) ? $translation->name : $this->name;
}
return $this->name;
}
public function getTranslatedDescriptionAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (!empty($languageCode) && $this->relationLoaded('translations')) {
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->description) ? $translation->description : $this->description;
}
return $this->description;
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
if ($column == "type") {
$query->where('type', $value);
} else {
$query->where((string)$column, (string)$value);
}
}
}
return $query;
}
public function getTranslatedKeyPointsAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
// ---------- Default / fallback ----------
if (!empty($this->key_points)) {
$defaultKeyPoints = is_array($this->key_points)
? $this->key_points
: (json_decode($this->key_points, true) ?? []);
} else {
$defaultKeyPoints = [];
}
// ---------- Translation ----------
if (!empty($languageCode) && $this->relationLoaded('translations')) {
$language = Language::select(['id', 'code'])
->where('code', $languageCode)
->first();
if ($language) {
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
if (!empty($translation?->key_points)) {
$translatedKeyPoints = is_array($translation->key_points)
? $translation->key_points
: json_decode($translation->key_points, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($translatedKeyPoints)) {
return $translatedKeyPoints;
}
}
}
}
return is_array($defaultKeyPoints) ? $defaultKeyPoints : [];
}
}

View File

@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class PackageCategory extends Model
{
use HasFactory;
protected $hidden = ['created_at', 'updated_at'];
protected $fillable = [
'category_id',
'package_id'
];
public function package()
{
return $this->belongsTo(Package::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class PackageTranslation extends Model
{
use HasFactory;
protected $fillable = [
'package_id',
'language_id',
'name',
'description',
'key_points',
];
public function package()
{
return $this->belongsTo(Package::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class PaymentConfiguration extends Model {
use HasFactory;
protected $fillable = [
'payment_method',
'api_key',
'secret_key',
'webhook_secret_key',
'currency_code',
'status',
'additional_data_1',
'additional_data_2',
'payment_mode',
'username',
'password'
];
}

View File

@@ -0,0 +1,49 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class PaymentTransaction extends Model {
protected $fillable = [
'user_id',
'package_id',
'amount',
'payment_gateway',
'order_id',
'payment_status',
'created_at',
'updated_at',
'payment_receipt'
];
use HasFactory;
protected $appends = ['payment_status_uper'];
public function user() {
return $this->belongsTo(User::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
return $query->where(function ($q) use ($search) {
$q->orWhere('id', 'LIKE', $search)
->orWhere('payment_gateway', 'LIKE', $search)
->orWhereHas('user', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
}
public function getPaymentReceiptAttribute($value)
{
if (!empty($value)) {
return url(Storage::url($value));
}
return $value;
}
public function getPaymentStatusUperAttribute()
{
$value = ucfirst($this->attributes['payment_status'] ?? '');
return $value;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ReportReason extends Model {
use HasFactory;
protected $fillable = [
'reason'
];
protected $appends = ['translated_reason'];
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('reason', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search);
});
return $query;
}
public function translations() {
return $this->hasMany(ReportReasonTranslation::class);
}
public function getTranslatedReasonAttribute() {
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (empty($languageCode)) {
return $this->name;
}
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (!$language) {
return $this->reason;
}
$nameTranslations = $this->relationLoaded('translations')
? $this->translations
: $this->translations()->get();
$translation = $nameTranslations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return !empty($translation?->reason) ? $translation->reason : $this->reason;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ReportReasonTranslation extends Model
{
use HasFactory;
protected $fillable = [
'report_reason_id',
'language_id',
'reason'
];
public function reportReason() {
return $this->belongsTo(ReportReason::class);
}
public function language() {
return $this->belongsTo(Language::class);
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class SellerRating extends Model
{
use HasFactory ,SoftDeletes;
protected $fillable = [
'review',
'ratings',
'seller_id',
'buyer_id',
'item_id',
'report_status',
'report_reason',
'report_rejected_reason'
];
public function seller() {
return $this->belongsTo(User::class,'seller_id');
}
public function buyer() {
return $this->belongsTo(User::class,'buyer_id');
}
public function item() {
return $this->belongsTo(Item::class)->withTrashed();
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
$query->where((string)$column, (string)$value);
}
}
return $query;
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
return $query->where(function ($q) use ($search) {
$q->orWhere('review', 'LIKE', $search)
->orWhere('ratings', 'LIKE', $search)
->orWhere('id', 'LIKE', $search)
->orWhere('report_status', 'LIKE', $search)
->orWhere('report_reason', 'LIKE', $search)
->orWhere('report_rejected_reason', 'LIKE', $search)
->orWhere('seller_id', 'LIKE', $search)
->orWhere('buyer_id', 'LIKE', $search)
->orWhere('item_id', 'LIKE', $search)
->orWhereHas('item', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('seller', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('buyer', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
}
public function scopeSort($query, $column, $order)
{
if ($column == "item_name") {
$query->leftJoin('items', 'items.id', '=', 'seller_ratings.item_id')
->orderBy('items.name', $order);
}
else if ($column == "seller_name") {
$query->leftJoin('users as seller_users', 'seller_users.id', '=', 'seller_ratings.seller_id')
->orderBy('seller_users.name', $order);
}
else if ($column == "buyer_name") {
$query->leftJoin('users as buyer_users', 'buyer_users.id', '=', 'seller_ratings.buyer_id')
->orderBy('buyer_users.name', $order);
}
else {
$query->orderBy($column, $order);
}
return $query->select('seller_ratings.*');
}
}

61
app/Models/SeoSetting.php Normal file
View File

@@ -0,0 +1,61 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Storage;
class SeoSetting extends Model
{
use HasFactory;
protected $fillable =[
'page',
'title',
'description',
'keywords',
'image'
];
protected $appends = ['translated_title','translated_description','translated_keywords'];
public function getImageAttribute($image) {
if (!empty($image)) {
return url(Storage::url($image));
}
return $image;
}
public function scopeSort($query, $column, $order) {
$query = $query->orderBy($column, $order);
return $query->select('seo_settings.*');
}
public function translations()
{
return $this->hasMany(SeoSettingsTranslation::class);
}
public function getTranslation($languageId = null)
{
$languageId = $languageId ?: Language::where('code', request()->header('Content-Language') ?? app()->getLocale())->value('id');
return $this->translations->where('language_id', $languageId)->first();
}
public function getTranslatedTitleAttribute()
{
return $this->getTranslation()?->title ?? $this->title;
}
public function getTranslatedDescriptionAttribute()
{
return $this->getTranslation()?->description ?? $this->description;
}
public function getTranslatedKeywordsAttribute()
{
return $this->getTranslation()?->keywords ?? $this->keywords;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SeoSettingsTranslation extends Model
{
use HasFactory;
protected $fillable = [
'seo_setting_id',
'language_id',
'title',
'description',
'keywords',
];
public function seoSetting()
{
return $this->belongsTo(SeoSetting::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

87
app/Models/Setting.php Normal file
View File

@@ -0,0 +1,87 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Str;
class Setting extends Model
{
use HasFactory;
public $table = 'settings';
protected $fillable = [
'name',
'value',
'type',
];
protected $hidden = [
'updated_at',
'deleted_at',
];
public function translations()
{
return $this->hasMany(SettingTranslation::class, 'setting_id');
}
public static function getValue(string $name)
{
return static::where('name', $name)->value('value');
}
public function getValueAttribute($value)
{
if (isset($this->attributes['type']) && $this->attributes['type'] == 'file') {
if (! empty($value)) {
/* Note : Because this is default logo so storage url will not work */
if (Str::contains($value, 'assets')) {
return asset($value);
}
return url(Storage::url($value));
}
return '';
}
return $value;
}
public function getTranslatedValueAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if (! empty($languageCode) && $this->relationLoaded('translations')) {
// Try to fetch requested language
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
// If not found, fall back to default language
if (! $language) {
$defaultLanguageCode = Setting::where('name', 'default_language')->value('value') ?? null;
if ($defaultLanguageCode) {
$language = Language::select(['id', 'code'])
->where('code', $defaultLanguageCode)
->first();
}
}
// Try to fetch translation if language exists
if ($language) {
$translation = $this->translations->first(function ($data) use ($language) {
return $data->language_id == $language->id;
});
return ! empty($translation?->translated_value) ? $translation->translated_value : $this->value;
}
}
return $this->value;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SettingTranslation extends Model
{
protected $fillable = [
'setting_id', 'language_id', 'translated_value',
];
public function setting()
{
return $this->belongsTo(Setting::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

115
app/Models/Slider.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Facades\Storage;
class Slider extends Model
{
use HasFactory;
protected $fillable = ['image', 'item_id', 'third_party_link', 'sequence', 'name', 'sold_out', 'country_id', 'state_id', 'city_id'];
public function item()
{
return $this->belongsTo(Item::class);
}
public function getImageAttribute($image)
{
if (! empty($image)) {
return url(Storage::url($image));
}
return $image;
}
public function scopeSearch($query, $search)
{
$search = '%'.$search.'%';
$query = $query->where(function ($q) use ($search) {
$q->orWhere('sequence', 'LIKE', $search)
->orWhere('model_type', 'LIKE', $search)
->orWhere('third_party_link', 'LIKE', $search)
->orWhere('model_id', 'LIKE', $search)
->orWhereHas('model', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
return $query;
}
public function scopeSort($query, $column, $order)
{
switch ($column) {
case 'model_name':
$query->when(request('model_type') === 'App\\Models\\Item', function ($q) use ($order) {
$q->leftJoin('items', 'items.id', '=', 'sliders.model_id')
->orderBy('items.name', $order);
});
$query->when(request('model_type') === 'App\\Models\\Category', function ($q) use ($order) {
$q->leftJoin('categories', 'categories.id', '=', 'sliders.model_id')
->orderBy('categories.name', $order);
});
break;
case 'item_name':
$query->leftJoin('items', 'items.id', '=', 'sliders.item_id')
->orderBy('items.name', $order);
break;
case 'country_name':
$query->leftJoin('countries', 'countries.id', '=', 'sliders.country_id')
->orderBy('countries.name', $order);
break;
case 'state_name':
$query->leftJoin('states', 'states.id', '=', 'sliders.state_id')
->orderBy('states.name', $order);
break;
case 'city_name':
$query->leftJoin('cities', 'cities.id', '=', 'sliders.city_id')
->orderBy('cities.name', $order);
break;
default:
$query->orderBy($column, $order);
break;
}
return $query->select('sliders.*');
}
public function categories()
{
return $this->hasOne(Category::class);
}
public function country()
{
return $this->belongsTo(Country::class, 'country_id');
}
public function state()
{
return $this->belongsTo(State::class, 'state_id');
}
public function city()
{
return $this->belongsTo(City::class, 'city_id');
}
public function model(): MorphTo
{
return $this->morphTo();
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SocialLogin extends Model {
use HasFactory;
protected $fillable = [
'firebase_id',
'type',
'user_id'
];
public function user() {
return $this->belongsTo(User::class);
}
}

97
app/Models/State.php Normal file
View File

@@ -0,0 +1,97 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class State extends Model {
use HasFactory;
protected $fillable = [
"id",
"name",
"state_code",
"latitude",
"longitude",
"type",
"country_id",
"country_code",
"fips_code",
"iso2",
"type",
"latitude",
"longitude",
"created_at",
"updated_at",
"flag",
"wikiDataId",
];
protected $appends = ['translated_name'];
protected $with = ['translations'];
public function country() {
return $this->belongsTo(Country::class);
}
public function cities() {
return $this->hasMany(City::class);
}
public function translations()
{
return $this->hasMany(StateTranslation::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('id', 'LIKE', $search)
->orWhere('name', 'LIKE', $search)
->orWhere('country_id', 'LIKE', $search)
->orWhere('state_code', 'LIKE', $search)
->orWhereHas('country', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
return $query;
}
public function scopeSort($query, $column, $order) {
if ($column == "country_name") {
$query = $query->leftjoin('countries', 'countries.id', '=', 'states.country_id')->orderBy('countries.name', $order);
} else {
$query = $query->orderBy($column, $order);
}
return $query->select('states.*');
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
if($column == "country_name") {
$query->whereHas('country', function ($query) use ($value) {
$query->where('country_id', $value);
});
}
else {
$query->where((string)$column, (string)$value);
}
}
}
return $query;
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translations = $this->relationLoaded('translations') ? $this->translations : $this->translations()->get();
$translation = $translations->firstWhere('language_id', $language->id);
return $translation?->name ?? $this->name;
}
return $this->name;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class StateTranslation extends Model
{
use HasFactory;
protected $fillable = ['state_id', 'language_id', 'name'];
public function state()
{
return $this->belongsTo(State::class);
}
public function language()
{
return $this->belongsTo(Language::class);
}
}

48
app/Models/Tip.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tip extends Model {
use HasFactory, SoftDeletes;
protected $fillable = [
'description'
];
protected $appends = ['translated_name'];
public function translations() {
return $this->hasMany(TipTranslation::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
return $query->where(function ($q) use ($search) {
$q->orWhere('description', 'LIKE', $search)
->orWhereHas('translations', function ($q) use ($search) {
$q->where('description', 'LIKE', $search);
});
});
}
public function getTranslatedNameAttribute() {
$languageCode = request()->header('Content-Language');
if (!empty($languageCode) && $this->relationLoaded('translations')) {
// NOTE : This code can be done in Cache
$language = Language::select(['id', 'code'])->where('code', $languageCode)->first();
if (empty($language)) {
return $this->description;
}
$translation = $this->translations->first(static function ($data) use ($language) {
return $data->language_id == $language->id;
});
return $translation->description ?? $this->description;
}
return $this->description;
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class TipTranslation extends Model {
protected $fillable = [
'description',
'language_id',
'tip_id'
];
public function language() {
return $this->belongsTo(Language::class);
}
public function tip() {
return $this->belongsTo(Tip::class);
}
}

107
app/Models/User.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Storage;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasPermissions;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable {
use HasApiTokens, HasFactory, Notifiable, HasRoles, SoftDeletes, HasPermissions;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'mobile',
'password',
'type',
'firebase_id',
'profile',
'address',
'notification',
'country_code',
'show_personal_details',
'is_verified',
'auto_approve_item',
'region_code'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getProfileAttribute($image) {
if (!empty($image) && !filter_var($image, FILTER_VALIDATE_URL)) {
return url(Storage::url($image));
}
return $image;
}
public function items() {
return $this->hasMany(Item::class);
}
public function sellerReview() {
return $this->hasMany(SellerRating::class , 'seller_id');
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
return $query->where(function ($q) use ($search) {
$q->orWhere('email', 'LIKE', $search)
->orWhere('mobile', 'LIKE', $search)
->orWhere('name', 'LIKE', $search)
->orWhere('type', 'LIKE', $search)
->orWhere('notification', 'LIKE', $search)
->orWhere('firebase_id', 'LIKE', $search)
->orWhere('address', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search);
});
}
public function user_reports() {
return $this->hasMany(UserReports::class);
}
public function fcm_tokens() {
return $this->hasMany(UserFcmToken::class);
}
public function getStatusAttribute($value)
{
if ($this->deleted_at) {
return "inactive";
}
if ($this->expiry_date && $this->expiry_date < Carbon::now()) {
return "expired";
}
return $value;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserFcmToken extends Model {
use HasFactory;
protected $fillable = [
'fcm_token',
'user_id',
'created_at',
'updated_at',
'platform_type'
];
public function user() {
return $this->belongsTo(User::class);
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class UserPurchasedPackage extends Model {
use HasFactory;
protected $fillable = [
'user_id',
'package_id',
'start_date',
'end_date',
'total_limit',
'used_limit',
'payment_transactions_id',
'listing_duration_type' ,
'listing_duration_days'
];
protected $appends = ['remaining_days', 'remaining_item_limit', 'status'];
public function package() {
return $this->belongsTo(Package::class);
}
public function user() {
return $this->belongsTo(User::class, 'user_id');
}
public function PaymentTransaction() {
return $this->belongsTo(PaymentTransaction::class);
}
public function scopeOnlyActive($query) {
return $query->where('user_id', Auth::user()->id)->whereDate('start_date', '<=', date('Y-m-d'))->where(function ($q) {
$q->whereDate('end_date', '>', date('Y-m-d'))->orWhereNull('end_date');
})->where(function ($q) {
$q->whereColumn('used_limit', '<', 'total_limit')->orWhereNull('total_limit');
})->orderBy('end_date', 'asc');
}
public function getRemainingDaysAttribute() {
if (!empty($this->end_date)) {
$startDate = Carbon::createFromFormat('Y-m-d', $this->start_date);
$endDate = Carbon::createFromFormat('Y-m-d', $this->end_date);
return $startDate->diffInDays($endDate);
}
return "unlimited";
}
public function getStatusAttribute()
{
if (empty($this->end_date)) {
return "Active"; // Or "Unlimited" if you prefer
}
$endDate = Carbon::createFromFormat('Y-m-d', $this->end_date);
$now = Carbon::now();
return $now->lessThanOrEqualTo($endDate) ? "Active" : "Expired";
}
public function getRemainingItemLimitAttribute() {
if (!empty($this->total_limit)) {
return $this->total_limit - $this->used_limit;
}
return "unlimited";
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('user_id', 'LIKE', $search)
->orWhere('package_id', 'LIKE', $search)
->orWhere('start_date', 'LIKE', $search)
->orWhere('end_date', 'LIKE', $search)
->orWhere('total_limit', 'LIKE', $search)
->orWhere('used_limit', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search)
->orWhereHas('package', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('user', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
return $query;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserReports extends Model {
use HasFactory;
protected $fillable = [
'id',
'report_reason_id',
'item_id',
'user_id',
'other_message',
'reason'
];
public function user() {
return $this->belongsTo(User::class);
}
public function report_reason() {
return $this->belongsTo(ReportReason::class);
}
public function item() {
return $this->belongsTo(Item::class);
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
$query = $query->where(function ($q) use ($search) {
$q->orWhere('report_reason_id', 'LIKE', $search)
->orWhere('item_id', 'LIKE', $search)
->orWhere('user_id', 'LIKE', $search)
->orWhere('other_message', 'LIKE', $search)
->orWhere('reason', 'LIKE', $search)
->orWhere('created_at', 'LIKE', $search)
->orWhere('updated_at', 'LIKE', $search)
->orWhereHas('report_reason', function ($q) use ($search) {
$q->where('reason', 'LIKE', $search);
})->orWhereHas('item', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
})->orWhereHas('user', function ($q) use ($search) {
$q->where('name', 'LIKE', $search);
});
});
return $query;
}
public function scopeSort($query, $column, $order) {
if ($column == "item_name") {
$query = $query->leftjoin('items', 'items.id', '=', 'user_reports.item_id')->orderBy('items.name', $order);
} else if ($column == "user_name") {
$query = $query->leftjoin('users', 'users.id', '=', 'user_reports.user_id')->orderBy('users.name', $order);
} else if ($column == "report_reason_name") {
$query = $query->leftjoin('report_reasons', 'report_reasons.id', '=', 'user_reports.report_reason_id')->orderBy('report_reasons.reason', $order);
} else {
$query = $query->orderBy($column, $order);
}
return $query->select('user_reports.*');
}
public function scopeFilter($query, $filterObject) {
if (!empty($filterObject)) {
foreach ($filterObject as $column => $value) {
$query->where((string)$column, (string)$value);
}
}
return $query;
}
public function getStatusAttribute($value) {
if ($this->deleted_at) {
return "inactive";
}
return $value;
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Throwable;
class VerificationField extends Model
{
use HasFactory , SoftDeletes;
protected $fillable = [
'name',
'type',
'status',
'values',
'min_length',
'max_length',
'is_required',
'deleted_at'
];
protected $hidden = ['created_at', 'updated_at'];
protected $appends = ['translated_name', 'translated_value'];
public function getValuesAttribute($value) {
try {
return array_values(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
} catch (Throwable) {
return $value;
}
}
public function scopeSearch($query, $search) {
$search = "%" . $search . "%";
return $query->where(function ($q) use ($search) {
$q->orWhere('name', 'LIKE', $search)
->orWhere('type', 'LIKE', $search)
->orWhere('values', 'LIKE', $search)
->orWhere('status', 'LIKE', $search);
});
}
public function user() {
return $this->belongsTo(User::class);
}
public function values()
{
return $this->hasMany(VerificationFieldValue::class);
}
public function verification_field_values()
{
return $this->hasMany(VerificationFieldValue::class, 'verification_field_id');
}
public function translations()
{
return $this->hasMany(VerificationFieldsTranslation::class, 'verification_field_id');
}
public function getTranslatedNameAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
// Find the language record
$language = Language::where('code', $languageCode)->first();
// If translations relationship is not loaded, load it
if (!$this->relationLoaded('translations')) {
$this->load('translations');
}
if ($language) {
$translation = $this->translations->first(function ($data) use ($language) {
return $data->language_id == $language->id;
});
return $translation->name ?? null; // return null if translation is missing
}
return null; // No language found
}
public function getTranslatedValueAttribute()
{
$languageCode = request()->header('Content-Language') ?? app()->getLocale();
if ($this->relationLoaded('translations')) {
$language = Language::where('code', $languageCode)->first();
if ($language) {
$translation = $this->translations->first(fn($t) => $t->language_id == $language->id);
return $translation && !empty($translation->value)
? $translation->value
: $this->values;
}
}
return $this->values;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class VerificationFieldValue extends Model
{
use HasFactory;
protected $fillable = [
'verification_field_id',
'value',
'flag',
'user_id',
'verification_request_id'
];
public function verification_field()
{
return $this->belongsTo(VerificationField::class, 'verification_field_id', 'id');
}
// Relationship with the VerificationRequest model
public function verification_request()
{
return $this->belongsTo(VerificationRequest::class, 'verification_request_id', 'id');
}
// public function getValueAttribute($value) {
// try {
// return array_values(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
// } catch (JsonException) {
// return $value;
// }
// }
public function getValueAttribute($value) {
if(str_contains($value,"verification_field_files")){
return url(Storage::url($value));
}
return $value;
}
public function user()
{
return $this->belongsTo(User::class);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Throwable;
class VerificationFieldsTranslation extends Model
{
use HasFactory;
protected $table = 'verification_fields_translations';
protected $fillable = [
'verification_field_id',
'language_id',
'name',
'value',
];
/**
* Get the custom field that owns this translation.
*/
public function verificationfield()
{
return $this->belongsTo(VerificationField::class);
}
/**
* Get the language for this translation.
*/
public function language()
{
return $this->belongsTo(Language::class);
}
public function getValueAttribute($value) {
try {
return array_values(json_decode($value, true, 512, JSON_THROW_ON_ERROR));
} catch (Throwable) {
return $value;
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class VerificationRequest extends Model
{
use HasFactory;
protected $fillable = [
'verification_field_value_id',
'user_id',
'status',
'rejection_reason'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function verification_field_values()
{
return $this->hasMany(VerificationFieldValue::class, 'verification_request_id', 'id');
}
public function scopeOwner($query){
return $query->where('user_id', auth()->id());
}
public function scopeSort($query, $column, $order) {
if ($column == "user_name") {
return $query->leftJoin('users', 'users.id', '=', 'verification_requests.user_id')
->orderBy('users.name', $order)
->select('verification_requests.*');
}
return $query->orderBy($column, $order);
}
}