Как я могу создать зависимое правило проверки в Nova? - PullRequest
1 голос
/ 09 июля 2019

У меня есть следующие поля для ресурса в Nova:

Select::make('Type')
    ->options([
        'video' => 'Video',
        'download' => 'Download',
        ])
    ->rules('required'),    

File::make('File', 'file_name')
    ->disk('local')
    ->path('/files')

Я пытаюсь настроить различные правила проверки для поля «Файл» в зависимости от значения поля типа. Например, при типе загрузки допускается использование мимов документов и максимальный размер 1 МБ, в то время как при установке в качестве видео принимается мимов видеофайл и максимальный размер 30 МБ.

Я действительно нигде не пытался добиться этого.

Я просмотрел документы , и ни объекты правил проверки , ни пользовательские правила закрытия не помогут мне, так как я не смогу получить доступ к значению поле типа из них.

Точно так же я думал о расширении объекта NovaRequest, как можно было бы сделать с FormRequest , но это не сделало бы проверку внешнего интерфейса, которую применяет Nova.

Есть ли способ добиться этого, которого мне не хватает?

Ответы [ 2 ]

0 голосов
/ 25 июля 2019

Теперь у меня есть эта работа через учебное пособие, предоставленное здесь от Джона Билса, который также жалуется на то, что Nova не отвечает на запросы форм Laravel автоматически.

1: Создать запрос на ресурс Nova, который расширяет форму-запрос:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;


class StoreResourceRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // Users authorized to make the request are:
        // - users updating themselves.
        // - staff
        // - guests creating a new user.


        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {

        $rules = self::ruleGetter($this);


        if(empty($this->user())) {
            $rules = array_merge_recursive($rules, self::creationRuleGetter($this));
        } else {
            $rules = array_merge_recursive($rules, self::updateRuleGetter($this));
        }

        return $rules;
    }

    public static function ruleGetter( $request, $rule = null ) {

        $rules = [
            'type' =>  ['required',Rule::in(['video', 'download'])],
        ];

        if($request['type'] == 'download'){
            $rules['file_name'] = ['required','mimes:jpeg,png,jpg,doc,docx,pdf','max:1000'];
        } 

        if($request['type'] == 'video'){
            $rules['file_name'] = ['required','mimes:mp4','max:50000'];
        }

        if(!empty($rule)) {
            if(isset($rules[$rule])) {
                return $rules[$rule];
            }
            return '';
        }
        return $rules;
    }

    public static function creationRuleGetter( $request, $rule = null ) {
        $rules = [

        ];


        if(!empty($rule)) {
            if(isset($rules[$rule])) {
                return $rules[$rule];
            }
            return '';
        }
        return $rules;

    }

    public static function updateRuleGetter( $request, $rule = null ) {


        $rules = [

        ];

        if(!empty($rule)) {
            if(isset($rules[$rule])) {
                return $rules[$rule];
            }
            return '';
        }
        return $rules;
    }

}

2: Обновите ресурс Nova, чтобы загрузить эти правила:

namespace App\Nova;

use App\Http\Requests\StoreResourceRequest;

//...

public function fields(Request $request)
{
    return [
        //...

        Select::make('Type')
        ->options([
            'video' => 'Video',
            'download' => 'Download',
        ])
        ->rules(StoreResourceRequest::ruleGetter($request, 'type')),

        File::make('File', 'file_name')
        ->rules(StoreResourceRequest::ruleGetter($request, 'file_name'))

    ];
}

Вышеуказанное работает для обоих типов проверки и сохраняет правильное значение в базе данных. Нова может нормально взаимодействовать с файлом.

Жаль, что это не встроено в Nova, и логика проверки должна быть продублирована.

0 голосов
/ 10 июля 2019

Возможно, вам нужно использовать большое имя пакета nova-dependency-container. Вы можете прочитать, как использовать его в novapackage. Примечания:

Вот мой код ресурса Document Nova. Удачного кодирования, спросите меня, если вам нужно!

<?php

namespace App\Nova;

use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\File;
use Laravel\Nova\Fields\Select;
use Illuminate\Http\Request;
use Laravel\Nova\Http\Requests\NovaRequest;
use Epartment\NovaDependencyContainer\HasDependencies;
use Epartment\NovaDependencyContainer\NovaDependencyContainer;

class Document extends Resource
{
    use HasDependencies;
    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = 'App\Document';

    /**
     * The single value that should be used to represent the resource when being displayed.
     *
     * @var string
     */
    public static $title = 'id';

    /**
     * The columns that should be searched.
     *
     * @var array
     */
    public static $search = [
        'id',
    ];

    /**
     * Get the fields displayed by the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Select::make('Type','type')
            ->options([
                'video' => 'Video',
                'download' => 'Download',
                ])
            ->rules('required'),
            NovaDependencyContainer::make([
                File::make('Video File','file_name')
                ->storeOriginalName('file_name')
                ->rules('required','mimes:mpga,mp2,mp2a,mp3,m2a,m3a,mp4,flv','max:30000')  //unit max is Kb
            ])->dependsOn('type', 'video'),
            NovaDependencyContainer::make([
                File::make('Document File', 'file_name')
                ->storeOriginalName('file_name')
                ->rules('required','mimes:jpeg,png,jpg,doc,docx,pdf','max:1000') 
            ])->dependsOn('type', 'download'),
        ];
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function filters(Request $request)
    {
        return [];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function lenses(Request $request)
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function actions(Request $request)
    {
        return [];
    }
}

Обновление:

С проблемой: «Когда я использую ваш код, он работает для загрузки видео (потому что это на первом месте), но затем загрузка документа выдает ошибку, которая должна быть подражателем видео, как указано в списке. Выбран ли документ или видео; применяются правила видео ».

Чтобы решить: используйте виртуальные атрибуты в модели, называемые Мутаторы Laravel , я слышал это несколько дней назад. Смотрите мои ниже коды:

// Model Laravel: app\Document.php
class Document extends Model
{
    public function getFileNameVideoAttribute()
    {
        if ($this->type == "video") {
            return $this->file_name;
        }
        return;
    }
    public function setFileNameVideoAttribute($value)
    {
        $this->attributes['file_name'] = $value;
    }
    public function getFileNameDocumentAttribute()
    {
        if ($this->type == "download") {
            return $this->file_name;
        }
        return;
    }
    public function setFileNameDocumentAttribute($value)
    {
        $this->attributes['file_name'] = $value;
    }
}
// Model Nova: app\Nova\Document.php
    public function fields(Request $request)
    {
        return [
            ID::make()->sortable(),
            Select::make('Type','type')
            ->options([
                'video' => 'Video',
                'download' => 'Download',
                ])
            ->rules('required'),
            NovaDependencyContainer::make([
                File::make('Video File','file_name_video')
                ->storeOriginalName('file_name')
                ->rules('required','mimes:mpga,mp2,mp2a,mp3,m2a,m3a,mp4,flv','max:30000')  //unit max is Kb
            ])->dependsOn('type', 'video'),
            NovaDependencyContainer::make([
                File::make('Document File', 'file_name_document')
                ->storeOriginalName('file_name')
                ->rules('required','mimes:jpeg,png,jpg,doc,docx,pdf','max:1000') 
            ])->dependsOn('type', 'download'),
        ];
    }
...