- Added actions for creating, updating, deleting, force deleting, and restoring recipes. - Introduced input classes for each action to handle data validation and transfer. - Implemented DTOs for recipes to facilitate data transfer between layers. - Updated RecipeController to utilize new actions and input classes. - Enhanced recipe model to manage picture URLs and storage. - Updated frontend components to handle new data structures and display images correctly.
75 lines
3.2 KiB
PHP
75 lines
3.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Requests\Back\Recipes;
|
|
|
|
use App\Cqs\Actions\Recipes\Update\UpdateRecipeInput;
|
|
use App\Models\Recipe;
|
|
use Domain\Models\ValueObjects\Products\ProductCategory;
|
|
use Domain\Models\ValueObjects\Recipes\ConsumptionTime;
|
|
use Domain\Models\ValueObjects\Recipes\Inspiration;
|
|
use Domain\Models\ValueObjects\Recipes\Season;
|
|
use Illuminate\Validation\Rule;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Uwil\Storage\Lib\ValueObjects\StorageFilePath;
|
|
|
|
class UpdateRecipeRequest extends StoreRecipeRequest
|
|
{
|
|
public function toUpdateRecipeInput(?Recipe $recipe = null): UpdateRecipeInput
|
|
{
|
|
$recipe ??= $this->route('recipe');
|
|
if (! $recipe instanceof Recipe) {
|
|
throw ValidationException::withMessages([
|
|
'recipe' => ['The recipe is invalid.'],
|
|
]);
|
|
}
|
|
|
|
$picture = null;
|
|
if ($this->hasFile('picture')) {
|
|
$picture = $this->storeFile($this->file('picture'));
|
|
} elseif ($this->filled('picture')) {
|
|
$picture = new StorageFilePath($this->string('picture')->value());
|
|
} elseif ($recipe->picture !== null) {
|
|
$picture = $recipe->picture;
|
|
}
|
|
|
|
return new UpdateRecipeInput(
|
|
id: $recipe->getId(),
|
|
name: $this->string('name')->trim()->value(),
|
|
seoTitle: $this->string('seo_title')->trim()->value(),
|
|
seoDescription: $this->string('seo_description')->trim()->value(),
|
|
productCategory: $this->enum('product_category', ProductCategory::class, ProductCategory::HARD_BOILED_EGGS),
|
|
consomptionTime: $this->enum('consomption_time', ConsumptionTime::class, ConsumptionTime::BREAK_FAST_BRUNCH),
|
|
inspiration: $this->enum('inspiration', Inspiration::class, Inspiration::FRENCH_COOKING),
|
|
season: $this->enum('season', Season::class, Season::ALL_YEAR),
|
|
description: $this->filled('description') ? $this->string('description')->trim()->value() : null,
|
|
details: $this->filled('details') ? $this->string('details')->trim()->value() : null,
|
|
ingredientsList: $this->string('ingredients_list')->trim()->value(),
|
|
preparationSteps: $this->string('preparation_steps')->trim()->value(),
|
|
tipsAndAdvices: $this->filled('tips_and_advices') ? $this->string('tips_and_advices')->trim()->value() : null,
|
|
picture: $picture,
|
|
pictureAlt: $this->string('picture_alt')->trim()->value(),
|
|
pictureTitle: $this->string('picture_title')->trim()->value(),
|
|
products: array_filter($this->array('products'), fn ($product) => is_string($product)),
|
|
);
|
|
}
|
|
|
|
public function rules(): array
|
|
{
|
|
return array_merge(parent::rules(), [
|
|
'picture' => [
|
|
'required',
|
|
$this->hasFile('picture')
|
|
? Rule::imageFile()
|
|
->max(self::MAX_FILE_SIZE_KB)
|
|
->dimensions(
|
|
Rule::dimensions()
|
|
->width(static::PICTURE_WIDTH)
|
|
->height(static::PICTURE_HEIGHT)
|
|
)
|
|
: 'string',
|
|
],
|
|
]);
|
|
}
|
|
}
|