Skip to content

Commit

Permalink
Add FileValidator
Browse files Browse the repository at this point in the history
  • Loading branch information
sukhwinder33445 committed Jul 28, 2022
1 parent 2b39615 commit b5b0cf2
Showing 1 changed file with 173 additions and 0 deletions.
173 changes: 173 additions & 0 deletions src/FileValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

namespace ipl\Validator;

use Icinga\Util\Format;
use ipl\I18n\Translation;
use LogicException;
use GuzzleHttp\Psr7\ServerRequest;

/** File Validator
*
* Validate file type and min or max size
*
* # Example Usage
* ```
* //var $this ipl\Html\Form
* $this->addElement(
* 'file',
* 'My File',
* [
* 'accept' => 'image/jpeg, image/png',
* 'label' => t('My File'),
* 'validators' => [
* 'File' => [
* 'request' => $this->getRequest(),
* 'mimeType' => 'image/jpeg, image/png',
* 'maxSize' => 65535,
* 'minSize' => 10,
* ]
* ]
* ]
* );
* ```
*/
class FileValidator extends BaseValidator
{
use Translation;

/**
* @var int|null
*/
protected $minSize;

/**
* @var int|null
*/
protected $maxSize;

/**
* @var array
*/
protected $allowedMimeTypes;

/**
* @var ServerRequest
*/
protected $request;

public function __construct(array $options)
{

if (empty($options['request']) || ! $options['request'] instanceof ServerRequest) {
throw new LogicException('The form request is required.');
}

$min = $options['minSize'] ?? null;
$max = $options['maxSize'] ?? null;
if ($max !== null && $min > $max) {
throw new LogicException(
sprintf(
'The minSize must be less than or equal to the maxSize, but minSize: %s and maxSize: %s given.',
$min,
$max
)
);
}

$this->minSize = $min;
$this->maxSize = $max;
$this->request = $options['request'];
$this->allowedMimeTypes = ! empty($options['mimeType'])
? explode(',', str_replace(' ', '', $options['mimeType']))
: [];
}

public function isValid($value)
{
// Multiple isValid() calls must not stack validation messages
$this->clearMessages();

foreach ($this->request->getUploadedFiles() as $uploadedFile) {
if (is_array($uploadedFile)) {
foreach ($uploadedFile as $file) {
if ($file->getError() === UPLOAD_ERR_NO_FILE) {
continue;
}

if (! $this->validateFile($file)) {
return false;
}
}
} else {
if ($uploadedFile->getError() === UPLOAD_ERR_NO_FILE) {
continue;
}

if (! $this->validateFile($uploadedFile)) {
return false;
}
}
}

return true;
}


private function validateFile($file): bool
{
if ($this->maxSize && $file->getSize() > $this->maxSize) {
$this->addMessage(sprintf(
$this->translate('File %s is bigger than the allowed maximum size of %s'),
$file->getClientFileName(),
Format::bytes($this->maxSize)
));

return false;
}

if ($this->minSize && $file->getSize() < $this->minSize) {
$this->addMessage(sprintf(
$this->translate('File %s is smaller than the minimum required size of %s'),
$file->getClientFileName(),
Format::bytes($this->minSize)
));

return false;
}

$hasRequiredMimeType = false;
foreach ($this->allowedMimeTypes as $type) {
$fileMimetype = $file->getClientMediaType();
if (($pos = strpos($type, '/*')) !== false) { // image/*
$typePrefix = substr($type, 0, $pos);
if (strpos($fileMimetype, $typePrefix) !== false) {
$hasRequiredMimeType = true;
break;
}
} elseif (strpos($type, '/') === false) { // .png
$typeExtension = trim($type, '.');
if (strpos($fileMimetype, $typeExtension) !== false) {
$hasRequiredMimeType = true;
break;
}
} elseif (strpos($fileMimetype, $type) !== false) { // image/png
$hasRequiredMimeType = true;
break;
}
}

if (! empty($this->allowedMimeTypes) && ! $hasRequiredMimeType) {
$this->addMessage(sprintf(
$this->translate('File %s is of type %s. Only %s allowed.'),
$file->getClientFileName(),
$file->getClientMediaType(),
implode(', ', $this->allowedMimeTypes)
));

return false;
}

return true;
}
}

0 comments on commit b5b0cf2

Please sign in to comment.