Skip to content

Commit

Permalink
Image validator additions (#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Mar 26, 2024
1 parent 48cbc71 commit 1bb0ab9
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 14 deletions.
4 changes: 4 additions & 0 deletions docs/guide/en/built-in-rules.md
Expand Up @@ -45,6 +45,10 @@ Here is a list of all available built-in rules, divided by category.
- [Count](../../../src/Rule/Count.php)
- [OneOf](../../../src/Rule/OneOf.php)

### File rules

- [Image](../../../src/Rule/Image.php)

### General purpose rules

- [Callback](../../../src/Rule/Callback.php)
Expand Down
83 changes: 73 additions & 10 deletions src/Rule/Image.php
Expand Up @@ -15,6 +15,10 @@
use Yiisoft\Validator\WhenInterface;

/**
* Defines validation options to check that a value is an image with a certain dimensions (optionally).
*
* > Currently not adapted for using with HEIF / HEIC formats.
*
* @see ImageHandler
*
* @psalm-import-type SkipOnEmptyValue from SkipOnEmptyInterface
Expand All @@ -28,6 +32,65 @@ final class Image implements RuleWithOptionsInterface, SkipOnErrorInterface, Whe
use WhenTrait;

/**
* @param int|null $width Expected exact width of validated image file.
* @param int|null $height Expected exact height of validated image file.
* @param int|null $minWidth Expected minimum width of validated image file.
* @param int|null $minHeight Expected minimum height of validated image file.
* @param int|null $maxWidth Expected maximum width of validated image file.
* @param int|null $maxHeight Expected maximum height of validated image file.
* @param string $notImageMessage A message used when the validated value is not valid image file.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
*
* @param string $notExactWidthMessage A message used when the width of validated image file doesn't exactly equal
* to {@see $width}.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
* - `{exactly}`: expected exact width of validated image file.
*
* @param string $notExactHeightMessage A message used when the height of validated image file doesn't exactly equal
* to {@see $height}.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
* - `{exactly}`: expected exact height of validated image file.
*
* @param string $tooSmallWidthMessage A message used when the width of validated image file is less than
* {@see $minWidth}.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
* - `{limit}`: expected minimum width of validated image file.
*
* @param string $tooSmallHeightMessage A message used when the height of validated image file is less than
* {@see $minHeight}.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
* - `{limit}`: expected minimum height of validated image file.
*
* @param string $tooLargeWidthMessage A message used when the width of validated image file is more than
* {@see $maxWidth}.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
* - `{limit}`: expected maximum width of validated image file.
*
* @param string $tooLargeHeightMessage A message used when the height of validated image file is more than
* {@see $maxHeight}.
*
* You may use the following placeholders in the message:
*
* - `{attribute}`: the translated label of the attribute being validated.
* - `{limit}`: expected maximum height of validated image file.
* @param bool|callable|null $skipOnEmpty Whether to skip this rule if the value validated is empty.
* See {@see SkipOnEmptyInterface}.
* @param bool $skipOnError Whether to skip this rule if any of the previous rules gave an error.
Expand All @@ -45,8 +108,8 @@ public function __construct(
private ?int $maxWidth = null,
private ?int $maxHeight = null,
private string $notImageMessage = 'The value must be an image.',
private string $notExactlyWidthMessage = 'The width of image "{attribute}" must be exactly {exactly, number} {exactly, plural, one{pixel} other{pixels}}.',
private string $notExactlyHeightMessage = 'The height of image "{attribute}" must be exactly {exactly, number} {exactly, plural, one{pixel} other{pixels}}.',
private string $notExactWidthMessage = 'The width of image "{attribute}" must be exactly {exactly, number} {exactly, plural, one{pixel} other{pixels}}.',
private string $notExactHeightMessage = 'The height of image "{attribute}" must be exactly {exactly, number} {exactly, plural, one{pixel} other{pixels}}.',
private string $tooSmallWidthMessage = 'The width of image "{attribute}" cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.',
private string $tooSmallHeightMessage = 'The height of image "{attribute}" cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.',
private string $tooLargeWidthMessage = 'The width of image "{attribute}" cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.',
Expand Down Expand Up @@ -92,14 +155,14 @@ public function getNotImageMessage(): string
return $this->notImageMessage;
}

public function getNotExactlyWidthMessage(): string
public function getNotExactWidthMessage(): string
{
return $this->notExactlyWidthMessage;
return $this->notExactWidthMessage;
}

public function getNotExactlyHeightMessage(): string
public function getNotExactHeightMessage(): string
{
return $this->notExactlyHeightMessage;
return $this->notExactHeightMessage;
}

public function getTooSmallWidthMessage(): string
Expand Down Expand Up @@ -135,14 +198,14 @@ public function getHandler(): string
public function getOptions(): array
{
return [
'notExactlyWidthMessage' => [
'template' => $this->notExactlyWidthMessage,
'notExactWidthMessage' => [
'template' => $this->notExactWidthMessage,
'parameters' => [
'exactly' => $this->width,
],
],
'notExactlyHeightMessage' => [
'template' => $this->notExactlyHeightMessage,
'notExactHeightMessage' => [
'template' => $this->notExactHeightMessage,
'parameters' => [
'exactly' => $this->height,
],
Expand Down
13 changes: 11 additions & 2 deletions src/Rule/ImageHandler.php
Expand Up @@ -10,6 +10,14 @@
use Yiisoft\Validator\RuleHandlerInterface;
use Yiisoft\Validator\ValidationContext;

use function is_array;
use function is_string;

/**
* Validates that a value is an image with a certain dimensions (optionally).
*
* @see Image
*/
final class ImageHandler implements RuleHandlerInterface
{
public function validate(mixed $value, object $rule, ValidationContext $context): Result
Expand All @@ -29,13 +37,13 @@ public function validate(mixed $value, object $rule, ValidationContext $context)
[$width, $height] = $info;

if ($rule->getWidth() !== null && $width !== $rule->getWidth()) {
$result->addError($rule->getNotExactlyWidthMessage(), [
$result->addError($rule->getNotExactWidthMessage(), [
'attribute' => $context->getTranslatedAttribute(),
'exactly' => $rule->getWidth(),
]);
}
if ($rule->getHeight() !== null && $height !== $rule->getHeight()) {
$result->addError($rule->getNotExactlyHeightMessage(), [
$result->addError($rule->getNotExactHeightMessage(), [
'attribute' => $context->getTranslatedAttribute(),
'exactly' => $rule->getHeight(),
]);
Expand Down Expand Up @@ -85,6 +93,7 @@ private function getImageInfo(mixed $value): ?array
/**
* @psalm-var (array{0:int,1:int}&array)|null $info Need for PHP 8.0 only
*/
// HEIF / HEIC formats are not supported.
$info = getimagesize($filePath);
return is_array($info) ? $info : null;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/Rule/Image/ImageTest.php
Expand Up @@ -106,13 +106,13 @@ public function dataOptions(): array
[
new Image(),
[
'notExactlyWidthMessage' => [
'notExactWidthMessage' => [
'template' => 'The width of image "{attribute}" must be exactly {exactly, number} {exactly, plural, one{pixel} other{pixels}}.',
'parameters' => [
'exactly' => null,
],
],
'notExactlyHeightMessage' => [
'notExactHeightMessage' => [
'template' => 'The height of image "{attribute}" must be exactly {exactly, number} {exactly, plural, one{pixel} other{pixels}}.',
'parameters' => [
'exactly' => null,
Expand Down

0 comments on commit 1bb0ab9

Please sign in to comment.