*/ protected $fillable = [ 'customer_id', 'rating_id', 'rate', 'rating_type', ]; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'rate' => RatingEnum::class, ]; // * METHODS /** * Get all ratings data. * * @param \App\Models\Product|\App\Models\Recipe $model * @return array */ public static function resetCache(Product|Recipe $model): array { Cache::forget(sprintf('%s-ratings', $model->slug)); return self::getRatings($model); } /** * Get all ratings data. * * @param \App\Models\Product|\App\Models\Recipe $model * @return array */ public static function getRatings(Product|Recipe $model): array { return Cache::remember(sprintf('%s-ratings', $model->slug), 86400, function () use ($model) { /** @var \App\Models\Customer|null customerModel */ $customerModel = auth('club')->user(); return [ 'total' => $model->ratings()->count(), 'totalRate' => round($model->ratings()->get()->avg(function (Rating $model) { return $model->rate->value(); }), 1), 'ratings' => $model->ratings()->inRandomOrder() ->take(6)->with('customer')->get()->each(function (Rating $rating) { $rating->customer_username = $rating->customer->username; return $rating; }), 'ratingType' => get_class($model), 'customerRating' => $customerModel ? $model->ratings()->where('customer_id', $customerModel->getkey())->first() : null, ]; }); } /** * Create a SchemaOrg. * * @param \Illuminate\Support\Collection $modelCollection * @return \Spatie\SchemaOrg\AggregateRating */ public static function toSchemaOrg(Collection $modelCollection): \Spatie\SchemaOrg\AggregateRating { return Schema::aggregateRating() ->ratingValue(self::getAverageRating($modelCollection)) ->bestRating(5) ->worstRating(1) ->ratingCount($modelCollection->count()); } /** * Calculate and return the average rating of rating collection. * * @param \Illuminate\Support\Collection $modelCollection * @return float */ public static function getAverageRating(Collection $modelCollection): float { return round($modelCollection->avg(function (Rating $model) { return $model->rate->value(); }), 1); } // * RELATIONSHIPS /** * Get all of the products that are favorite by this customer. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function customer(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Customer::class); } /** * Get the parent rateable model (Product or Recipe). * * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ public function model(): \Illuminate\Database\Eloquent\Relations\MorphTo { return $this->morphTo('rating'); } }