262 lines
7.2 KiB
PHP
262 lines
7.2 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);
|
|
}) : $query;
|
|
}
|
|
|
|
public function scopeByTags($query, $tags)
|
|
{
|
|
return $tags ? $query->whereHas('tags', function ($query) use ($tags) {
|
|
$query->byIds($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'
|
|
]
|
|
];
|
|
}
|
|
}
|