getError() === UPLOAD_ERR_NO_FILE; } public function __construct(FileInput $subject) { $this->subject = $subject; } /** * @return UploadedFileInterface|UploadedFileInterface[] */ public function getValue() { $value = $this->subject->value; // Run filters ~after~ validation, so that is_uploaded_file() // validation is not affected by filters. if (! $this->subject->isValid) { return $value; } $filter = $this->subject->getFilterChain(); if (is_array($value)) { // Multi file input (multiple attribute set) $newValue = []; foreach ($value as $fileData) { $newValue[] = $filter->filter($fileData); } return $newValue; } // Single file input return $filter->filter($value); } /** * @param mixed $context Extra "context" to provide the validator * @return bool */ public function isValid($context = null) { $rawValue = $this->subject->getRawValue(); $validator = $this->injectUploadValidator($this->subject->getValidatorChain()); if (is_array($rawValue)) { // Multi file input (multiple attribute set) $this->subject->isValid = true; foreach ($rawValue as $value) { if (! $validator->isValid($value, $context)) { $this->subject->isValid = false; return false; // Do not continue processing files if validation fails } } return true; // We return early from the loop if validation fails } // Single file input $this->subject->isValid = $validator->isValid($rawValue, $context); return $this->subject->isValid; } /** * @return ValidatorChain */ protected function injectUploadValidator(ValidatorChain $chain) { if (! $this->subject->autoPrependUploadValidator) { return $chain; } // Check if Upload validator is already first in chain $validators = $chain->getValidators(); if ( isset($validators[0]['instance']) && $validators[0]['instance'] instanceof UploadValidator ) { $this->subject->autoPrependUploadValidator = false; return $chain; } $chain->prependByName(UploadValidator::class, [], true); $this->subject->autoPrependUploadValidator = false; return $chain; } }