diff --git a/composer.json b/composer.json index c63365de..ae59e960 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "phpstan/phpstan-deprecation-rules": "^0.12", "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^9.3", + "psr/http-message": "^1.0", "respect/coding-standard": "^3.0", "squizlabs/php_codesniffer": "^3.5", "symfony/validator": "^3.0||^4.0", diff --git a/docs/rules/Readable.md b/docs/rules/Readable.md index ee239592..53d88da3 100644 --- a/docs/rules/Readable.md +++ b/docs/rules/Readable.md @@ -16,6 +16,7 @@ v::readable()->validate('file.txt'); // true Version | Description --------|------------- + 2.1.0 | Add PSR-7 support 0.5.0 | Created *** diff --git a/docs/rules/Size.md b/docs/rules/Size.md index ff876625..db325d66 100644 --- a/docs/rules/Size.md +++ b/docs/rules/Size.md @@ -40,6 +40,7 @@ Message template for this validator includes `{{minSize}}` and `{{maxSize}}`. Version | Description --------|------------- + 2.1.0 | Add PSR-7 support 1.0.0 | Created *** diff --git a/docs/rules/Uploaded.md b/docs/rules/Uploaded.md index 8be5e8d1..59766275 100644 --- a/docs/rules/Uploaded.md +++ b/docs/rules/Uploaded.md @@ -16,6 +16,7 @@ v::uploaded()->validate('/path/of/an/uploaded/file'); // true Version | Description --------|------------- + 2.1.0 | Add PSR-7 support 0.5.0 | Created *** diff --git a/docs/rules/Writable.md b/docs/rules/Writable.md index d0d0fb22..1e987c50 100644 --- a/docs/rules/Writable.md +++ b/docs/rules/Writable.md @@ -16,6 +16,7 @@ v::writable()->validate('file.txt'); // true Version | Description --------|------------- + 2.1.0 | Add PSR-7 support 0.5.0 | Created *** diff --git a/library/Rules/Readable.php b/library/Rules/Readable.php index f9d48687..89e1e98b 100644 --- a/library/Rules/Readable.php +++ b/library/Rules/Readable.php @@ -13,6 +13,7 @@ declare(strict_types=1); namespace Respect\Validation\Rules; +use Psr\Http\Message\StreamInterface; use SplFileInfo; use function is_readable; @@ -35,6 +36,10 @@ final class Readable extends AbstractRule return $input->isReadable(); } + if ($input instanceof StreamInterface) { + return $input->isReadable(); + } + return is_string($input) && is_readable($input); } } diff --git a/library/Rules/Size.php b/library/Rules/Size.php index 20f07e09..e2900eb2 100644 --- a/library/Rules/Size.php +++ b/library/Rules/Size.php @@ -13,6 +13,8 @@ declare(strict_types=1); namespace Respect\Validation\Rules; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UploadedFileInterface; use Respect\Validation\Exceptions\ComponentException; use SplFileInfo; @@ -27,6 +29,7 @@ use function sprintf; * * @author Danilo Correa * @author Henrique Moody + * @author Felipe Stival */ final class Size extends AbstractRule { @@ -71,6 +74,14 @@ final class Size extends AbstractRule return $this->isValidSize($input->getSize()); } + if ($input instanceof UploadedFileInterface) { + return $this->isValidSize($input->getSize()); + } + + if ($input instanceof StreamInterface) { + return $this->isValidSize($input->getSize()); + } + if (is_string($input)) { return $this->isValidSize((int) filesize($input)); } diff --git a/library/Rules/Uploaded.php b/library/Rules/Uploaded.php index a9b0fd0b..d2deeb28 100644 --- a/library/Rules/Uploaded.php +++ b/library/Rules/Uploaded.php @@ -13,6 +13,7 @@ declare(strict_types=1); namespace Respect\Validation\Rules; +use Psr\Http\Message\UploadedFileInterface; use SplFileInfo; use function is_scalar; @@ -35,6 +36,10 @@ final class Uploaded extends AbstractRule return $this->validate($input->getPathname()); } + if ($input instanceof UploadedFileInterface) { + return true; + } + if (!is_scalar($input)) { return false; } diff --git a/library/Rules/Writable.php b/library/Rules/Writable.php index ae84deaf..ea313a59 100644 --- a/library/Rules/Writable.php +++ b/library/Rules/Writable.php @@ -13,6 +13,7 @@ declare(strict_types=1); namespace Respect\Validation\Rules; +use Psr\Http\Message\StreamInterface; use SplFileInfo; use function is_string; @@ -35,6 +36,10 @@ final class Writable extends AbstractRule return $input->isWritable(); } + if ($input instanceof StreamInterface) { + return $input->isWritable(); + } + return is_string($input) && is_writable($input); } } diff --git a/tests/unit/Rules/ReadableTest.php b/tests/unit/Rules/ReadableTest.php index db66af51..645d319b 100644 --- a/tests/unit/Rules/ReadableTest.php +++ b/tests/unit/Rules/ReadableTest.php @@ -13,6 +13,7 @@ declare(strict_types=1); namespace Respect\Validation\Rules; +use Psr\Http\Message\StreamInterface; use Respect\Validation\Test\RuleTestCase; use SplFileInfo; use stdClass; @@ -38,6 +39,7 @@ final class ReadableTest extends RuleTestCase return [ [$rule, $file], [$rule, new SplFileInfo($file)], + [$rule, $this->createPsr7Stream(true)], ]; } @@ -53,6 +55,15 @@ final class ReadableTest extends RuleTestCase [$rule, $file], [$rule, new SplFileInfo($file)], [$rule, new stdClass()], + [$rule, $this->createPsr7Stream(false)], ]; } + + private function createPsr7Stream(bool $isReadable): StreamInterface + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects(self::any())->method('isReadable')->willReturn($isReadable); + + return $stream; + } } diff --git a/tests/unit/Rules/SizeTest.php b/tests/unit/Rules/SizeTest.php index ab4270a9..eaaeacd8 100644 --- a/tests/unit/Rules/SizeTest.php +++ b/tests/unit/Rules/SizeTest.php @@ -15,6 +15,7 @@ namespace Respect\Validation\Rules; use org\bovigo\vfs\content\LargeFileContent; use org\bovigo\vfs\vfsStream; +use Psr\Http\Message\StreamInterface; use Respect\Validation\Exceptions\ComponentException; use Respect\Validation\Test\RuleTestCase; use SplFileInfo; @@ -71,6 +72,9 @@ final class SizeTest extends RuleTestCase ->withContent(LargeFileContent::withMegabytes(2)) ->at($root); + $psr7Stream1Mb = $this->createMock(StreamInterface::class); + $psr7Stream1Mb->expects(self::once())->method('getSize')->willReturn(1024); + return [ 'file with at least 3kb' => [new Size('3kb', null), $file2Kb->url()], 'file with up to 1kb' => [new Size(null, '1kb'), $file2Kb->url()], @@ -81,6 +85,7 @@ final class SizeTest extends RuleTestCase 'file between 1pb and 3pb' => [new Size('1pb', '3pb'), $file2Mb->url()], 'SplFileInfo instancia' => [new Size('1pb', '3pb'), new SplFileInfo($file2Mb->url())], 'parameter invalid' => [new Size('1pb', '3pb'), []], + 'PSR-7 stream' => [new Size('1MB', '1.1MB'), $psr7Stream1Mb], ]; } diff --git a/tests/unit/Rules/UploadedTest.php b/tests/unit/Rules/UploadedTest.php index 34c66b1a..d4de0de2 100644 --- a/tests/unit/Rules/UploadedTest.php +++ b/tests/unit/Rules/UploadedTest.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Respect\Validation\Rules; use PHPUnit\Framework\SkippedTestError; +use Psr\Http\Message\UploadedFileInterface; use Respect\Validation\Test\RuleTestCase; use SplFileInfo; use stdClass; @@ -44,6 +45,7 @@ final class UploadedTest extends RuleTestCase return [ [$rule, self::UPLOADED_FILENAME], [$rule, new SplFileInfo(self::UPLOADED_FILENAME)], + [$rule, $this->createMock(UploadedFileInterface::class)], ]; } diff --git a/tests/unit/Rules/WritableTest.php b/tests/unit/Rules/WritableTest.php index d7a6512c..0985f097 100644 --- a/tests/unit/Rules/WritableTest.php +++ b/tests/unit/Rules/WritableTest.php @@ -13,6 +13,7 @@ declare(strict_types=1); namespace Respect\Validation\Rules; +use Psr\Http\Message\StreamInterface; use Respect\Validation\Test\RuleTestCase; use SplFileInfo; use SplFileObject; @@ -44,6 +45,7 @@ final class WritableTest extends RuleTestCase 'writable directory' => [$sut, $this->getFixtureDirectory()], 'writable SplFileInfo file' => [$sut, new SplFileInfo($filename)], 'writable SplFileObject file' => [$sut, new SplFileObject($filename)], + 'writable PSR-7 stream' => [$sut, $this->createPsr7Stream(true)], ]; } @@ -58,6 +60,7 @@ final class WritableTest extends RuleTestCase $this->changeFileModeToUnwritable($filename); return [ + 'unwritable PSR-7 stream' => [$rule, $this->createPsr7Stream(false)], 'unwritable filename' => [$rule, $filename], 'unwritable SplFileInfo file' => [$rule, new SplFileInfo($filename)], 'unwritable SplFileObject file' => [$rule, new SplFileObject($filename)], @@ -72,6 +75,14 @@ final class WritableTest extends RuleTestCase ]; } + private function createPsr7Stream(bool $isWritable): StreamInterface + { + $stream = $this->createMock(StreamInterface::class); + $stream->expects(self::any())->method('isWritable')->willReturn($isWritable); + + return $stream; + } + private function changeFileModeToUnwritable(string $filename): void { chmod($filename, 0555);