ldc-legaulois/app/Models/Recipes.php
Jérémy Munsch de16379127 Optimize recipes query
optimize recipe.show requests

Products optimize requests
2021-03-25 08:26:55 +01:00

142 lines
4.1 KiB
PHP

<?php
namespace App\Models;
use App\Enums\RecipeDifficulty;
use App\Enums\RecipeType;
use Illuminate\Database\Eloquent\Model;
use Kwaadpepper\Enum\Traits\CastsEnums;
class Recipes extends Model
{
use CastsEnums;
protected $casts = [
'highlight' => 'boolean'
];
protected $enumCasts = [
'type' => RecipeType::class,
'difficulty' => RecipeDifficulty::class
];
public function articles()
{
return $this->belongsToMany(Articles::class, 'recipes_articles', 'recipe_id', 'article_id');
}
public function products()
{
return $this->belongsToMany(Products::class, 'recipes_products', 'recipe_id', 'product_id');
}
/**
* Get Associated Recipes
* @return \Illuminate\Database\Eloquent\Collection<Recipes>
*/
public function associatedRecipes()
{
$recipesLimit = 3;
$rangeID = $this->products()->first()->range->id ?? 0;
$preparationTime = $this->preparation_time ?? 0;
$cookingTime = $this->cooking_time ?? 0;
$recipes = Recipes::where('id', '!=', $this->id)
->whereHas('products.range', function ($q) use ($rangeID) {
$q->where('ranges.id', $rangeID);
})->inRandomOrder()->limit($recipesLimit)->get();
// With preparation time
if (count($recipes) < $recipesLimit) {
$recipes = $recipes->merge(Recipes::where('preparation_time', $preparationTime)
->inRandomOrder()
->limit($recipesLimit - count($recipes))
->get());
}
// With cooking time
if (count($recipes) < $recipesLimit) {
$recipes = $recipes->merge(Recipes::where('cooking_time', $cookingTime)
->inRandomOrder()
->limit($recipesLimit - count($recipes))
->get());
}
// Random
if (count($recipes) < $recipesLimit) {
$recipes = $recipes->merge(Recipes::limit($recipesLimit - count($recipes))
->inRandomOrder()
->limit($recipesLimit - count($recipes))
->get());
}
return $recipes;
}
public function rating()
{
return $this->hasOne(Rating::class);
}
public function customers()
{
return $this->belongsToMany(Customers::class);
}
public function consumptionTimes()
{
return $this->belongsTo(ConsumptionTimes::class, 'consumption_times_id');
}
public function notifiable()
{
return $this->morphOne(Notifications::class, 'notifiable');
}
/**
* Check if recipe has been rated by the user (in session also if not Auth)
* @return boolean
*/
public function hasBeenRatedByUser()
{
if (auth('customer')->check()) {
/** @var \App\Models\Customers $customer */
$customer = auth('customer')->user();
return is_null($customer->getRecipeRating($this)) ? false : true;
} else {
return session()->has(sprintf('recipes.rating.%s', $this->slug));
}
}
/**
* Set the recipes rating and memorize in session, or user
* @param string $rating
* @return void
*/
public function setRateForUserAndSave($rating)
{
$total = $this->rating->total + $rating;
$count = ++$this->rating->count;
$o = [
'total' => $total,
'count' => $count,
'rating' => floatval($total / $count)
];
if (!$this->rating->exists()) {
$this->attach(new Rating($o));
} else {
$this->rating->total = $o['total'];
$this->rating->rating = $o['rating'];
$this->rating->count = $o['count'];
$this->rating->save();
}
if (auth('customer')->check()) {
/** @var \App\Models\Customers $customer */
$customer = auth('customer')->user();
$customer->setRecipeRating($this, $rating);
} else {
session()->put(sprintf('recipes.rating.%s', $this->slug), $rating);
session()->save();
}
}
}