SPresnac's avatar

Request validation special

The task is to check, if an uploaded file is of a specific type (extention) and so i created a request validator for it like this:

class DocumentStoreRequest extends ApiRequestBase
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'ts'            => 'required|date_format:U',
            'file_type'     => 'required|integer|min:1|exists:clientDb.document_type,id',
            'file_notes'    => 'required|string|min:1',
            'binary'        => 'required_without:binary_name|file|mimes:avi,bmp,doc,docx,gif,jpeg,jpg,mp4,mpg,msg,pdf,png,ppt,pptx,tif,tiff,txt,xls,xlsx,application/vnd.ms-outlook',
            'binary_name'   => 'required_without:binary|string|min:1',
            'container_id'  => 'required|integer|exists:clientDb.document_container,id',

            'hp_id'         => 'integer|min:1',
            'posting_year'  => 'date_format:Y',
            'group'         => 'integer',
            'is_public'     => new RealBoolean(),
            'is_internal'   => new RealBoolean(),
            'webupload'     => new RealBoolean(),
            'poc'           => 'string|min:1|max:3',
        ];
    }
}

Just ignore the RealBoolean and think of it as boolean validator.

The Problem is in the "binary" check, where i want to check, if a file has a given extention. All works well, but when i want to upload .msg files (outlook messages), then the validation failes. When checking with mimetypes:application/vnd.ms-outlook it will work, but then all of the others will fail.

What i need to have is something like "check mime and when ths fails check "mimetypes" afterwards and only if both failed, the request fails. But how do i do this?

I hope, you can understand my problem and guide me in the right direction.

0 likes
3 replies
rodrigo.pedra's avatar
Level 56

Create a custom rule and have this check done there. You can add the ValidatesAttributes trait to use the underlying Laravel validation.

  1. Custom rule
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Validation\Concerns\ValidatesAttributes;

class MimeType implements Rule
{
    use ValidatesAttributes;

    /** @var array */
    private $extensions;

    /** @var array */
    private $mimeTypes;

    public function __construct($extensions, $mimeTypes)
    {
        $this->extensions = explode(',', $extensions);
        $this->mimeTypes = explode(',', $mimeTypes);
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        if ($this->validateMimes($attribute, $value, $this->extensions)) {
            return true;
        }

        return $this->validateMimetypes($attribute, $value, $this->mimeTypes);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The file :attribute is not of an allowed type.';
    }
}
  1. Usage
use App\Rules\MimeType;

class DocumentStoreRequest extends ApiRequestBase
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'binary' => [
                'required_without:binary_name',
                'file',
                new MimeType(
                   'avi,bmp,doc,docx,gif,jpeg,jpg,mp4,mpg,msg,pdf,png,ppt,pptx,tif,tiff,txt,xls,xlsx',
                   'application/vnd.ms-outlook'
                ),
            ],
        ];
    }
}
1 like
SPresnac's avatar

Thank you very much for this 😊

1 like

Please or to participate in this conversation.