HEX
Server: LiteSpeed
System: Linux php-prod-3.spaceapp.ru 5.15.0-151-generic #161-Ubuntu SMP Tue Jul 22 14:25:40 UTC 2025 x86_64
User: sarli3128 (1010)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /home/marketing.cfbon.ru/public_html/app/Http/Requests/Site/Menu/ProductRequest.php
<?php

namespace App\Http\Requests\Site\Menu;

use Illuminate\Foundation\Http\FormRequest;

class ProductRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    protected function prepareForValidation() : void
    {
        $variations = [];

        if ($this->has('variation_volume_id') && $this->has('variations_price')) {
            foreach ($this->variation_volume_id as $index => $id) {
                $variations[] = [
                    'volume_id' => $id,
                    'price' => $this->variations_price[$index] ?? null,
                ];
            }
        }

        $this->offsetUnset('variation_volume_id');
        $this->offsetUnset('variations_price');

        $this->merge([
            'has_volumes' => (bool) $this->input('has_volumes', false),
            'is_only_here' => (bool) $this->input('is_only_here', false),
            'variations' => empty($variations) ? null : $variations,
        ]);

    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        $rules = [
            'category_id' => 'required|exists:product_categories,id',
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'img' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:5120',
            'has_volumes' => 'nullable',
            'is_only_here' => 'nullable',
        ];

        if ($this->boolean('has_volumes')) {
            $rules['variations'] = [
                'required',
                'array',
                function ($attribute, $value, $fail) {
                    $volumeIds = collect($value)
                        ->pluck('volume_id')
                        ->filter();

                    if ($volumeIds->duplicates()->isNotEmpty()) {
                        $fail('Вариации не должны содержать повторяющиеся объемы.');
                    }
                },
            ];
            $rules['variations.*.volume_id'] = 'required|exists:volumes,id';
            $rules['variations.*.price'] = 'required|numeric|min:0';
        } else {
            $rules['price'] = 'required|numeric|min:0';
            $rules['size'] = 'nullable|string|max:255';
        }

        return $rules;
    }

    public function messages()
    {
        return [
            'category_id.required' => 'Пожалуйста, выберите категорию.',
            'category_id.exists' => 'Выбранная категория не существует.',

            'title.required' => 'Поле "Название товара" обязательно для заполнения.',
            'title.string' => 'Название товара должно быть строкой.',
            'title.max' => 'Название товара не должно превышать 255 символов.',

            'description.string' => 'Описание должно быть текстом.',

            'price.required' => 'Цена обязательна к заполнению.',
            'price.numeric' => 'Цена должна быть числом.',
            'price.min' => 'Цена не может быть отрицательной.',

            'size.string' => 'Вес/объем должен быть строкой.',
            'size.max' => 'Вес/объем не должен превышать 255 символов.',

            'variations.required' => 'Добавьте хотя бы один объем и цену.',

            'variations.*.volume_id.required' => 'Пожалуйста, выберите объем.',
            'variations.*.volume_id.exists' => 'Выбранный объем не существует.',

            'variations.*.price.required' => 'Цена обязательна для каждого объема.',
            'variations.*.price.numeric' => 'Цена должна быть числом.',
            'variations.*.price.min' => 'Цена не может быть отрицательной.',

            'img.image' => 'Файл должен быть изображением.',
            'img.mimes' => 'Изображение должно быть в формате: jpeg, png, jpg, gif или svg.',
            'img.max' => 'Поле "Изображение" должно быть не больше 5МБ.',
        ];
    }
}