summaryrefslogtreecommitdiffstats
path: root/vendor/ipl/validator/src/FileValidator.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ipl/validator/src/FileValidator.php')
-rw-r--r--vendor/ipl/validator/src/FileValidator.php248
1 files changed, 248 insertions, 0 deletions
diff --git a/vendor/ipl/validator/src/FileValidator.php b/vendor/ipl/validator/src/FileValidator.php
new file mode 100644
index 0000000..8c5b90e
--- /dev/null
+++ b/vendor/ipl/validator/src/FileValidator.php
@@ -0,0 +1,248 @@
+<?php
+
+namespace ipl\Validator;
+
+use ipl\I18n\Translation;
+use ipl\Stdlib\Str;
+use LogicException;
+use Psr\Http\Message\UploadedFileInterface;
+
+/**
+ * Validates an uploaded file
+ */
+class FileValidator extends BaseValidator
+{
+ use Translation;
+
+ /** @var int Minimum allowed file size */
+ protected $minSize;
+
+ /** @var ?int Maximum allowed file size */
+ protected $maxSize;
+
+ /** @var ?string[] Allowed mime types */
+ protected $allowedMimeTypes;
+
+ /** @var ?int Maximum allowed file name length */
+ protected $maxFileNameLength;
+
+ /**
+ * Create a new FileValidator
+ *
+ * Optional options:
+ * - minSize: (int) Minimum allowed file size, by default 0
+ * - maxSize: (int) Maximum allowed file size, by default no limit
+ * - maxFileNameLength: (int) Maximum allowed file name length, by default no limit
+ * - mimeType: (array) Allowed mime types, by default no restriction
+ */
+ public function __construct(array $options = [])
+ {
+ $this
+ ->setMinSize($options['minSize'] ?? 0)
+ ->setMaxSize($options['maxSize'] ?? null)
+ ->setMaxFileNameLength($options['maxFileNameLength'] ?? null)
+ ->setAllowedMimeTypes($options['mimeType'] ?? null);
+ }
+
+ /**
+ * Get the minimum allowed file size
+ *
+ * @return int
+ */
+ public function getMinSize(): int
+ {
+ return $this->minSize;
+ }
+
+ /**
+ * Set the minimum allowed file size
+ *
+ * @param int $minSize
+ *
+ * @return $this
+ */
+ public function setMinSize(int $minSize): self
+ {
+ if (($max = $this->getMaxSize()) !== null && $minSize > $max) {
+ throw new LogicException(
+ sprintf(
+ 'The minSize must be less than or equal to the maxSize, but minSize: %d and maxSize: %d given.',
+ $minSize,
+ $max
+ )
+ );
+ }
+
+ $this->minSize = $minSize;
+
+ return $this;
+ }
+
+ /**
+ * Get the maximum allowed file size
+ *
+ * @return ?int
+ */
+ public function getMaxSize(): ?int
+ {
+ return $this->maxSize;
+ }
+
+ /**
+ * Set the maximum allowed file size
+ *
+ * @param ?int $maxSize
+ *
+ * @return $this
+ */
+ public function setMaxSize(?int $maxSize): self
+ {
+ if ($maxSize !== null && ($min = $this->getMinSize()) !== null && $maxSize < $min) {
+ throw new LogicException(
+ sprintf(
+ 'The minSize must be less than or equal to the maxSize, but minSize: %d and maxSize: %d given.',
+ $min,
+ $maxSize
+ )
+ );
+ }
+
+ $this->maxSize = $maxSize;
+
+ return $this;
+ }
+
+ /**
+ * Get the allowed file mime types
+ *
+ * @return ?string[]
+ */
+ public function getAllowedMimeTypes(): ?array
+ {
+ return $this->allowedMimeTypes;
+ }
+
+ /**
+ * Set the allowed file mime types
+ *
+ * @param ?string[] $allowedMimeTypes
+ *
+ * @return $this
+ */
+ public function setAllowedMimeTypes(?array $allowedMimeTypes): self
+ {
+ $this->allowedMimeTypes = $allowedMimeTypes;
+
+ return $this;
+ }
+
+ /**
+ * Get maximum allowed file name length
+ *
+ * @return ?int
+ */
+ public function getMaxFileNameLength(): ?int
+ {
+ return $this->maxFileNameLength;
+ }
+
+ /**
+ * Set maximum allowed file name length
+ *
+ * @param ?int $maxFileNameLength
+ *
+ * @return $this
+ */
+ public function setMaxFileNameLength(?int $maxFileNameLength): self
+ {
+ $this->maxFileNameLength = $maxFileNameLength;
+
+ return $this;
+ }
+
+ public function isValid($value)
+ {
+ // Multiple isValid() calls must not stack validation messages
+ $this->clearMessages();
+
+ if (is_array($value)) {
+ foreach ($value as $file) {
+ if (! $this->validateFile($file)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return $this->validateFile($value);
+ }
+
+
+ private function validateFile(UploadedFileInterface $file): bool
+ {
+ $isValid = true;
+ if ($this->getMaxSize() && $file->getSize() > $this->getMaxSize()) {
+ $this->addMessage(sprintf(
+ $this->translate('File %s is bigger than the allowed maximum size of %d'),
+ $file->getClientFileName(),
+ $this->getMaxSize()
+ ));
+
+ $isValid = false;
+ }
+
+ if ($this->getMinSize() && $file->getSize() < $this->getMinSize()) {
+ $this->addMessage(sprintf(
+ $this->translate('File %s is smaller than the minimum required size of %d'),
+ $file->getClientFileName(),
+ $this->getMinSize()
+ ));
+
+ $isValid = false;
+ }
+
+ if ($this->getMaxFileNameLength()) {
+ $strValidator = new StringLengthValidator(['max' => $this->getMaxFileNameLength()]);
+
+ if (! $strValidator->isValid($file->getClientFilename())) {
+ $this->addMessage(sprintf(
+ $this->translate('File name is longer than the allowed length of %d characters.'),
+ $this->maxFileNameLength
+ ));
+
+ $isValid = false;
+ }
+ }
+
+ if (! empty($this->getAllowedMimeTypes())) {
+ $hasAllowedMimeType = false;
+ foreach ($this->getAllowedMimeTypes() as $type) {
+ $fileMimetype = $file->getClientMediaType();
+ if (($pos = strpos($type, '/*')) !== false) { // image/*
+ $typePrefix = substr($type, 0, $pos);
+ if (Str::startsWith($fileMimetype, $typePrefix)) {
+ $hasAllowedMimeType = true;
+ break;
+ }
+ } elseif ($fileMimetype === $type) { // image/png
+ $hasAllowedMimeType = true;
+ break;
+ }
+ }
+
+ if (! $hasAllowedMimeType) {
+ $this->addMessage(sprintf(
+ $this->translate('File %s is of type %s. Only %s allowed.'),
+ $file->getClientFileName(),
+ $file->getClientMediaType(),
+ implode(', ', $this->allowedMimeTypes)
+ ));
+
+ $isValid = false;
+ }
+ }
+
+ return $isValid;
+ }
+}