Files
opensem/app/Models/Shop/Article.php
2025-01-03 03:46:45 +01:00

270 lines
7.7 KiB
PHP

<?php
namespace App\Models\Shop;
use App\Models\Botanic\Specie;
use App\Models\Botanic\Variety;
use App\Traits\Model\HasComments;
use App\Traits\Model\Imageable;
use Cviebrock\EloquentSluggable\Sluggable;
use Fico7489\Laravel\EloquentJoin\Traits\EloquentJoin;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Kirschbaum\PowerJoins\PowerJoins;
use Laravel\Scout\Searchable;
use RalphJSmit\Laravel\SEO\Support\HasSEO;
use RalphJSmit\Laravel\SEO\Support\SEOData;
use Rinvex\Categories\Traits\Categorizable;
use Rinvex\Tags\Traits\Taggable;
use Spatie\MediaLibrary\HasMedia;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
use Venturecraft\Revisionable\RevisionableTrait;
use Wildside\Userstamps\Userstamps;
class Article extends Model implements HasMedia
{
use Categorizable;
use EloquentJoin;
use HasComments;
use HasRelationships;
use HasSEO;
use Imageable;
use Powerjoins;
use RevisionableTrait;
use Searchable;
use Sluggable;
use SoftDeletes;
use Taggable;
use UserStamps;
protected $guarded = ['id'];
protected $table = 'shop_articles';
protected $dontKeepRevisionOf = ['updated_by', 'updated_at'];
public function article_nature(): BelongsTo
{
return $this->belongsTo(ArticleNature::class);
}
public function offers(): HasMany
{
return $this->hasMany(Offer::class);
}
public function price_lists()
{
return $this->hasManyDeep(
PriceList::class,
[Offer::class, Tariff::class],
['article_id', 'id'],
['id', 'tariff_id'],
);
}
public function prices()
{
return $this->hasManyDeep(
PriceListValue::class,
[Offer::class, Tariff::class, PriceList::class],
['article_id', 'id', 'tariff_id'],
['id', 'tariff_id', 'id'],
);
}
public function product(): MorphTo
{
return $this->morphTo();
}
public function siblings(): HasMany
{
return $this->hasMany(Article::class, 'name', 'name');
}
public function tags(): MorphToMany
{
return $this->morphToMany(Tag::class, 'taggable');
}
public function tariffs(): HasManyThrough
{
return $this->hasManyThrough(Tariff::class, Offer::class, 'article_id', 'id', 'id', 'tariff_id');
// return $this->belongsToMany(Tariff::class, Offer::$table, 'id', 'id', 'tariff_id', 'tariff_id');
}
public function scopeByArticle($query, $id)
{
return $query->where($this->table.'.id', $id);
}
public function scopeByAutocomplete($query, $str)
{
return $query->where($this->table.'.name', 'LIKE', '%'.$str.'%');
}
public function scopeRawSearch($query, $str)
{
return $query->where($this->table.'.name', 'LIKE', '%'.$str.'%');
}
public function scopeByArticleNature($query, $id)
{
return $id ? $query->where($this->table.'.article_nature_id', $id) : $query;
}
public function scopeByArticleNatures($query, $ids)
{
return $ids ? $query->whereIn($this->table.'.article_nature_id', $ids) : $query;
}
public function scopeByCategories($query, $categoriesId)
{
return $categoriesId ? $query->whereHas('categories', function ($query) use ($categoriesId) {
$query->whereIn('id', $categoriesId);
}) : $query;
}
public function scopeByCategoryParent($query, $categoryId)
{
$category = Category::find($categoryId);
return $categoryId ? $query->whereHas('categories', function ($query) use ($category) {
$query->where('_lft', '>=', $category->_lft)->where('_rgt', '<=', $category->_rgt);
}) : $query;
}
public function scopeByCategory($query, $categoryId)
{
return $categoryId ? $query->whereHas('categories', function ($query) use ($categoryId) {
$query->where('id', $categoryId);
}) : $query;
}
public function scopeBotanic($query)
{
return $query->whereIn($this->table.'.product_type', [Variety::class, Specie::class]);
}
public function scopeByIDs($query, $ids)
{
return $query->whereIN($this->table.'.id', $ids);
}
public function scopeMerchandise($query)
{
return $query->byProduct(Merchandise::class);
}
public function scopeVisible($query)
{
return $query->where($this->table.'.visible', 1);
}
public function scopeHomepage($query)
{
return $query->where($this->table.'.homepage', 1);
}
public function scopeByProduct($query, $model)
{
return $model ? $query->where($this->table.'.product_type', $model) : $query;
}
public function scopeByProductId($query, $productId)
{
return $productId ? $query->where($this->table.'.product_id', $productId) : $query;
}
public function scopeBySlug($query, $slug)
{
return $slug ? $query->where($this->table.'.slug', $slug) : $query;
}
public function scopeByTag($query, $tagId)
{
return $tagId ? $query->whereHas('tags', function ($query) use ($tagId) {
$query->byId($tagId);
})->orWhereHasMorph('product', [Variety::class], function($query) use ($tagId) {
$query->whereHas('tags', function ($query) use ($tagId) {
$query->where('id', $tagId);
});
}) : $query;
}
public function scopeByTags($query, $tags)
{
return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
$query->byIds($tags);
})->orWhereHasMorph('product', [Variety::class], function($query) use ($tags) {
$query->whereHas('tags', function ($query) use ($tags) {
$query->whereIntegerInRaw('id', $tags);
});
}) : $query;
}
public function scopeWithOffers($query)
{
return $query->has('offers');
}
public function scopeWithAvailableOffers($query, $saleChannelId = false)
{
return $query->whereHas('offers', function ($query) use ($saleChannelId) {
$query->active()->byStockAvailable();
if ($saleChannelId) {
$query->bySaleChannel($saleChannelId);
}
});
}
public function toSearchableArray(): array
{
$description = $this->description;
$product = $this->product ?? false;
if (is_object($product)) {
$description .= ' '.$product ? $product->description : '';
$description .= ' '.$product ? $product->plus ?? '' : '';
$specie = $product ? $product->specie : false;
$description .= ' '.$specie ? $specie->description ?? '' : '';
}
return [
'id' => (int) $this->id,
'article_nature_id' => $this->article_nature_id,
'name' => $this->name,
'description' => html_entity_decode(strip_tags($description)),
];
}
public function getDynamicSEOData(): SEOData
{
// $pathToFeaturedImageRelativeToPublicPath = // ..;
// Override only the properties you want:
return new SEOData(
title: $this->name,
description: $this->description,
// image: $pathToFeaturedImageRelativeToPublicPath,
);
}
public function sluggable(): array
{
return [
'slug' => [
'source' => 'name',
],
];
}
}