From ed4c633f5d3aef14916762edd945e09a6f12ed22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Houlgrave?= Date: Mon, 26 Feb 2018 17:31:48 +0100 Subject: [PATCH 01/18] Add webp support --- src/File/IsImage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/File/IsImage.php b/src/File/IsImage.php index 9f80d0d3b..dc3f773f7 100644 --- a/src/File/IsImage.php +++ b/src/File/IsImage.php @@ -74,6 +74,7 @@ public function __construct($options = []) 'image/vnd.djvu', 'image/vnd.fpx', 'image/vnd.net-fpx', + 'image/webp', 'image/x-cmu-raster', 'image/x-cmx', 'image/x-coreldraw', From b93c3aa038cd14414b5d849d8d2ce7312bf4d091 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 9 May 2018 04:06:25 +0700 Subject: [PATCH 02/18] count optimization --- src/Explode.php | 2 +- src/File/FilesSize.php | 2 +- src/File/ImageSize.php | 2 +- src/File/Size.php | 2 +- src/File/Upload.php | 4 ++-- src/File/UploadFile.php | 2 +- src/StringLength.php | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Explode.php b/src/Explode.php index 6ff3b58ec..b5500772c 100644 --- a/src/Explode.php +++ b/src/Explode.php @@ -206,6 +206,6 @@ public function isValid($value, $context = null) } } - return count($this->abstractOptions['messages']) == 0; + return ! $this->abstractOptions['messages']; } } diff --git a/src/File/FilesSize.php b/src/File/FilesSize.php index 079c7a291..2cb206cfe 100644 --- a/src/File/FilesSize.php +++ b/src/File/FilesSize.php @@ -151,7 +151,7 @@ public function isValid($value, $file = null) } } - if (count($this->getMessages()) > 0) { + if ($this->getMessages()) { return false; } diff --git a/src/File/ImageSize.php b/src/File/ImageSize.php index 62e1d1f7a..47fe12914 100644 --- a/src/File/ImageSize.php +++ b/src/File/ImageSize.php @@ -383,7 +383,7 @@ public function isValid($value, $file = null) $this->error(self::HEIGHT_TOO_BIG); } - if (count($this->getMessages()) > 0) { + if ($this->getMessages()) { return false; } diff --git a/src/File/Size.php b/src/File/Size.php index 80a9701b0..45b90c01e 100644 --- a/src/File/Size.php +++ b/src/File/Size.php @@ -292,7 +292,7 @@ public function isValid($value, $file = null) } } - if (count($this->getMessages()) > 0) { + if ($this->getMessages()) { return false; } diff --git a/src/File/Upload.php b/src/File/Upload.php index 33b664b3a..213c949ac 100644 --- a/src/File/Upload.php +++ b/src/File/Upload.php @@ -92,7 +92,7 @@ public function getFiles($file = null) } } - if (count($return) === 0) { + if (! $return) { throw new Exception\InvalidArgumentException("The file '$file' was not found"); } @@ -205,7 +205,7 @@ public function isValid($value, $file = null) } } - if (count($this->getMessages()) > 0) { + if ($this->getMessages()) { return false; } diff --git a/src/File/UploadFile.php b/src/File/UploadFile.php index 4b46f5532..15e494aed 100644 --- a/src/File/UploadFile.php +++ b/src/File/UploadFile.php @@ -114,7 +114,7 @@ public function isValid($value) break; } - if (count($this->getMessages()) > 0) { + if ($this->getMessages()) { return false; } diff --git a/src/StringLength.php b/src/StringLength.php index 7d87185c9..1fda85716 100644 --- a/src/StringLength.php +++ b/src/StringLength.php @@ -226,7 +226,7 @@ public function isValid($value) $this->error(self::TOO_LONG); } - if (count($this->getMessages())) { + if ($this->getMessages()) { return false; } From 57225904d42767ee0f6c05fe7d5246bc969127a2 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 13 Dec 2018 11:19:05 -0600 Subject: [PATCH 03/18] Adds CHANGELOG entry for #220 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6390e378a..17506def2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file, in reverse ### Added -- Nothing. +- [#220](https://github.com/zendframework/zend-validator/pull/220) adds image/webp to the list of known image types for the `IsImage` validator. ### Changed From 4d467e27f7922a6dbb0eb1f577d95118535320a5 Mon Sep 17 00:00:00 2001 From: Sasha Alex Romanenko Date: Wed, 15 Aug 2018 18:47:26 -0400 Subject: [PATCH 04/18] Add PSR-7 support to UploadFile and Upload validators. --- composer.json | 5 +- composer.lock | 117 ++++++++++++++++++++- src/File/Upload.php | 35 ++++++- src/File/UploadFile.php | 10 +- test/File/UploadFileTest.php | 17 ++++ test/File/UploadTest.php | 191 +++++++++++++++++++++++++++++++++++ 6 files changed, 366 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 17f291573..ec0a26964 100644 --- a/composer.json +++ b/composer.json @@ -29,9 +29,12 @@ "zendframework/zend-session": "^2.8", "zendframework/zend-uri": "^2.5", "phpunit/PHPUnit": "^6.0.8 || ^5.7.15", - "zendframework/zend-coding-standard": "~1.0.0" + "zendframework/zend-coding-standard": "~1.0.0", + "psr/http-message": "^1.0", + "zendframework/zend-diactoros": "^1.8" }, "suggest": { + "psr/http-message": "Zend\\Filter component, required by PsrFileInput validator", "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", diff --git a/composer.lock b/composer.lock index 3452b249f..fd9b214f9 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "202752ae2a5ef78cc657783a20e371cb", + "content-hash": "3cfd67f8701bfaeb36e59c6affad0453", "packages": [ { "name": "container-interop/container-interop", @@ -828,6 +828,56 @@ ], "time": "2016-12-08T20:27:08+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.1", @@ -1735,6 +1785,69 @@ ], "time": "2016-08-09T19:28:55+00:00" }, + { + "name": "zendframework/zend-diactoros", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-diactoros.git", + "reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/3e4edb822c942f37ade0d09579cfbab11e2fee87", + "reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7", + "zendframework/zend-coding-standard": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev", + "dev-develop": "1.9.x-dev", + "dev-release-2.0": "2.0.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php" + ], + "psr-4": { + "Zend\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://github.com/zendframework/zend-diactoros", + "keywords": [ + "http", + "psr", + "psr-7" + ], + "time": "2018-08-10T14:16:32+00:00" + }, { "name": "zendframework/zend-escaper", "version": "2.5.2", diff --git a/src/File/Upload.php b/src/File/Upload.php index 213c949ac..4c1dc45cf 100644 --- a/src/File/Upload.php +++ b/src/File/Upload.php @@ -10,6 +10,7 @@ namespace Zend\Validator\File; use Countable; +use Psr\Http\Message\UploadedFileInterface; use Zend\Validator\AbstractValidator; use Zend\Validator\Exception; @@ -87,7 +88,11 @@ public function getFiles($file = null) $return[$file] = $this->options['files'][$name]; } - if ($content['name'] === $file) { + if ($content instanceof UploadedFileInterface) { + if($content->getClientFilename() === $file) { + $return[$name] = $this->options['files'][$name]; + } + } else if ($content['name'] === $file) { $return[$name] = $this->options['files'][$name]; } } @@ -124,7 +129,7 @@ public function setFiles($files = []) } foreach ($this->options['files'] as $file => $content) { - if (! isset($content['error'])) { + if (!($content instanceof UploadedFileInterface) && ! isset($content['error'])) { unset($this->options['files'][$file]); } } @@ -148,6 +153,18 @@ public function isValid($value, $file = null) $files = array_merge($files, $this->getFiles($value)); } else { foreach ($this->getFiles() as $file => $content) { + if ($content instanceof UploadedFileInterface) { + if ($content->getClientFilename() === $value) { + $files = array_merge($files, $this->getFiles($file)); + } + + // PSR cannot search by tmp_name because it does not have + // a public interface to get it, only user defined name + // from form field. + continue; + } + + if (isset($content['name']) && ($content['name'] === $value)) { $files = array_merge($files, $this->getFiles($file)); } @@ -164,9 +181,15 @@ public function isValid($value, $file = null) foreach ($files as $file => $content) { $this->value = $file; - switch ($content['error']) { + $error = ($content instanceof UploadedFileInterface) ? + $content->getError() : $content['error']; + switch ($error) { case 0: - if (! is_uploaded_file($content['tmp_name'])) { + $tmpFile = ($content instanceof UploadedFileInterface) ? + $content->getStream()->getMetadata('uri') : + $content['tmp_name']; + + if (! is_uploaded_file($tmpFile)) { $this->throwError($content, self::ATTACK); } break; @@ -215,7 +238,7 @@ public function isValid($value, $file = null) /** * Throws an error of the given type * - * @param string $file + * @param array|string|UploadedFileInterface $file * @param string $errorType * @return false */ @@ -228,6 +251,8 @@ protected function throwError($file, $errorType) } } elseif (is_string($file)) { $this->value = $file; + } elseif ($file instanceof UploadedFileInterface) { + $this->value = $file->getClientFilename(); } } diff --git a/src/File/UploadFile.php b/src/File/UploadFile.php index 15e494aed..74ff28c83 100644 --- a/src/File/UploadFile.php +++ b/src/File/UploadFile.php @@ -9,6 +9,7 @@ namespace Zend\Validator\File; +use Psr\Http\Message\UploadedFileInterface; use Zend\Validator\AbstractValidator; use Zend\Validator\Exception; @@ -50,7 +51,7 @@ class UploadFile extends AbstractValidator /** * Returns true if and only if the file was uploaded without errors * - * @param string $value File to check for upload errors + * @param string|array|UploadedFileInterface $value File to check for upload errors * @return bool * @throws Exception\InvalidArgumentException */ @@ -65,6 +66,13 @@ public function isValid($value) $file = $value['tmp_name']; $filename = $value['name']; $error = $value['error']; + } elseif ($value instanceof UploadedFileInterface) { + /** @var UploadedFileInterface $value */ + $filename = $value->getClientFilename(); + $error = $value->getError(); + if (UPLOAD_ERR_OK === $error) { + $file = $value->getStream()->getMetadata('uri'); + } } else { $file = $value; $filename = basename($file); diff --git a/test/File/UploadFileTest.php b/test/File/UploadFileTest.php index e46825f4f..30ede1bfa 100644 --- a/test/File/UploadFileTest.php +++ b/test/File/UploadFileTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Validator\File; use PHPUnit\Framework\TestCase; +use Zend\Diactoros\UploadedFile; use Zend\Validator\Exception\InvalidArgumentException; use Zend\Validator\File; @@ -49,6 +50,22 @@ public function uploadErrorsTestDataProvider() $errorType, ]; } + + // Diactoros does not have UNKNOWN error type. + unset($errorTypes[9]); + foreach ($errorTypes as $errorCode => $errorType) { + $data[] = [ + new UploadedFile( + // need a real file for Stream to not throw exceptions + $testSizeFile, + 200 + $errorCode, + $errorCode, + 'test' . $errorCode, + 'text' + ), + $errorType, + ]; + } return $data; } diff --git a/test/File/UploadTest.php b/test/File/UploadTest.php index c6a969dea..39bf3edab 100644 --- a/test/File/UploadTest.php +++ b/test/File/UploadTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Validator\File; use PHPUnit\Framework\TestCase; +use Zend\Diactoros\UploadedFile; use Zend\Validator\Exception\InvalidArgumentException; use Zend\Validator\File; @@ -131,6 +132,117 @@ public function testBasic() $this->assertArrayHasKey('fileUploadErrorFileNotFound', $validator->getMessages()); } + /** + * Ensures that the validator follows expected behavior + * + * @return void + */ + public function testPsrBasic() + { + $files = [ + 'test' => new UploadedFile( + __DIR__ . '/_files/testsize.mo', // has to be real file + 200, + 0, + 'test1', + 'text' + ), + 'test2' => new UploadedFile( + 'tmp_test2', + 202, + 1, + 'test2', + 'text2' + ), + 'test3' => new UploadedFile( + 'tmp_test3', + 203, + 2, + 'test3', + 'text3' + ), + 'test4' => new UploadedFile( + 'tmp_test4', + 204, + 3, + 'test4', + 'text4' + ), + 'test5' => new UploadedFile( + 'tmp_test5', + 205, + 4, + 'test5', + 'text5' + ), + 'test6' => new UploadedFile( + 'tmp_test6', + 206, + 5, + 'test6', + 'text6' + ), + 'test7' => new UploadedFile( + 'tmp_test7', + 207, + 6, + 'test7', + 'text7' + ), + 'test8' => new UploadedFile( + 'tmp_test8', + 208, + 7, + 'test8', + 'text8' + ), + 'test9' => new UploadedFile( + 'tmp_test9', + 209, + 8, + 'test9', + 'text9' + ) + ]; + + $validator = new File\Upload(); + $validator->setFiles($files); + $this->assertFalse($validator->isValid('test')); + $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test2')); + $this->assertArrayHasKey('fileUploadErrorIniSize', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test3')); + $this->assertArrayHasKey('fileUploadErrorFormSize', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test4')); + $this->assertArrayHasKey('fileUploadErrorPartial', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test5')); + $this->assertArrayHasKey('fileUploadErrorNoFile', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test6')); + $this->assertArrayHasKey('fileUploadErrorUnknown', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test7')); + $this->assertArrayHasKey('fileUploadErrorNoTmpDir', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test8')); + $this->assertArrayHasKey('fileUploadErrorCantWrite', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test9')); + $this->assertArrayHasKey('fileUploadErrorExtension', $validator->getMessages()); + + $this->assertFalse($validator->isValid('test1')); + $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); + + // not testing lookup by temp file name since PSR does not expose it + + $this->assertFalse($validator->isValid('test000')); + $this->assertArrayHasKey('fileUploadErrorFileNotFound', $validator->getMessages()); + } + /** * Ensures that getFiles() returns expected value * @@ -178,6 +290,35 @@ public function testGetFiles() $this->assertEquals([], $validator->getFiles('test5')); } + public function testPsrGetFiles() { + $files = [ + 'test' => new UploadedFile( + 'tmp_test1', + 200, + 0, + 'test1', + 'text' + ), + 'test2' => new UploadedFile( + 'tmp_test2', + 202, + 1, + 'test3', + 'text2' + ) + ]; + + $validator = new File\Upload(); + $validator->setFiles($files); + $this->assertEquals(['test' => $files['test']], $validator->getFiles('test')); + $this->assertEquals(['test' => $files['test']], $validator->getFiles('test1')); + $this->assertEquals(['test2' => $files['test2']], $validator->getFiles('test3')); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('was not found'); + $this->assertEquals([], $validator->getFiles('test5')); + } + /** * Ensures that setFiles() returns expected value * @@ -217,6 +358,29 @@ public function testSetFiles() $this->assertEquals($files, $validator->getFiles()); } + public function testPsrSetFiles() { + $psrFiles = [ + 'test4' => new UploadedFile( + 'tmp_test4', + 204, + 3, + 'test4', + 'text5' + ), + 'test5' => new UploadedFile( + 'tmp_test5', + 205, + 4, + 'test5', + 'text5' + ) + ]; + + $validator = new File\Upload(); + $validator->setFiles($psrFiles); + $this->assertEquals($psrFiles, $validator->getFiles()); + } + /** * @group ZF-10738 */ @@ -274,4 +438,31 @@ public function testErrorMessage() $validator->getMessages() ); } + + /** + * @group ZF-12128 + */ + public function testPsrErrorMessage() { + $files = [ + 'foo' => new UploadedFile( + 'tmp_bar', + 100, + 7, + 'bar', + 'text' + ) + ]; + + $validator = new File\Upload; + $validator->setFiles($files); + $validator->isValid('foo'); + + $this->assertEquals( + [ + 'fileUploadErrorCantWrite' => "File 'bar' can't be written", + ], + $validator->getMessages() + ); + $validator->setFiles($files); + } } From 8de0f11bbf72497ea4fed5ca4dc6232591b6611a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:10:14 +0100 Subject: [PATCH 05/18] Adds notice for installation requirements for db-validators --- doc/book/validators/db.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/book/validators/db.md b/doc/book/validators/db.md index f0434c83c..23d7d21f0 100644 --- a/doc/book/validators/db.md +++ b/doc/book/validators/db.md @@ -4,6 +4,16 @@ a means to test whether a record exists in a given table of a database, with a given value. +> ### Installation requirements +> +> `Zend\Validator\Db\NoRecordExists` and `Zend\Validator\Db\RecordExists` +> depends on the zend-db component, so be sure to have it installed before +> getting started: +> +> ```bash +> $ composer require zendframework/zend-db` +> ``` + ## Supported options The following options are supported for `Zend\Validator\Db\NoRecordExists` and From b7e4ed7e089a97686415785b4924b2568a0156ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:10:43 +0100 Subject: [PATCH 06/18] Adds notice for installation requirements for digits validator --- doc/book/validators/digits.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/book/validators/digits.md b/doc/book/validators/digits.md index ee2d7b69f..0792f78ea 100644 --- a/doc/book/validators/digits.md +++ b/doc/book/validators/digits.md @@ -2,6 +2,15 @@ `Zend\Validator\Digits` validates if a given value contains only digits. +> ### Installation requirements +> +> `Zend\Validator\Digits` depends on the zend-filter component, so be sure to +> have it installed before getting started: +> +> ```bash +> $ composer require zendframework/zend-filter` +> ``` + ## Supported options There are no additional options for `Zend\Validator\Digits`: From 7efbc4716f414f6def4dc6cd4ea69ef359dc0eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:11:01 +0100 Subject: [PATCH 07/18] Adds notice for installation requirements for sitmap-loc validator --- doc/book/validators/sitemap.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/book/validators/sitemap.md b/doc/book/validators/sitemap.md index 45228db65..1126febe3 100644 --- a/doc/book/validators/sitemap.md +++ b/doc/book/validators/sitemap.md @@ -47,6 +47,15 @@ $validator->isValid('yesterday'); // false [Zend\\Uri\\Uri::isValid()](https://zendframework.github.io/zend-uri/usage/#validating-the-uri) internally. +> ### Installation requirements +> +> `Zend\Validator\Sitemap\Loc` depends on the zend-uri component, so be sure to +> have it installed before getting started: +> +> ```bash +> $ composer require zendframework/zend-uri` +> ``` + ## Priority `Zend\Validator\Sitemap\Priority` validates whether a value is valid for using From 48fff29eb68aecd8c4bc56a7cb5d769c0d4cc617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:25:12 +0100 Subject: [PATCH 08/18] Adds name for entry page in MkDocs configuration --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 7bc382a3e..a2bf1a6ef 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,7 @@ docs_dir: doc/book site_dir: doc/html pages: - - index.md + - Home: index.md - Intro: intro.md - Reference: - "Validator Chains": validator-chains.md From de23232f3ebd2959de02a7369da8b82f885c438d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:25:47 +0100 Subject: [PATCH 09/18] Removes copyright notice from MkDocs configuration --- mkdocs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index a2bf1a6ef..5afcf29f3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -61,4 +61,3 @@ pages: site_name: zend-validator site_description: zend-validator repo_url: 'https://github.com/zendframework/zend-validator' -copyright: 'Copyright (c) 2016 Zend Technologies USA Inc.' From 8e3ccc25efc31812f9dabf337991b97d66fd5529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:26:04 +0100 Subject: [PATCH 10/18] Updates site description in MkDocs configuration --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 5afcf29f3..4db87840e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -59,5 +59,5 @@ pages: - UploadFile: validators/file/upload-file.md - WordCount: validators/file/word-count.md site_name: zend-validator -site_description: zend-validator +site_description: "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria." repo_url: 'https://github.com/zendframework/zend-validator' From 9898d6b791f3db223ce5925adcc56d85c22655fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Bru=CC=88ckner?= Date: Thu, 13 Dec 2018 20:26:43 +0100 Subject: [PATCH 11/18] Updates introduction page entries in MkDocs configuration --- mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 4db87840e..3902393a2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ docs_dir: doc/book site_dir: doc/html pages: - Home: index.md - - Intro: intro.md + - Introduction: intro.md - Reference: - "Validator Chains": validator-chains.md - "Writing Validators": writing-validators.md @@ -38,7 +38,7 @@ pages: - Uri: validators/uri.md - Uuid: validators/uuid.md - "File Validators": - - Intro: validators/file/intro.md + - Introduction: validators/file/intro.md - Count: validators/file/count.md - Crc32: validators/file/crc32.md - ExcludeExtension: validators/file/exclude-extension.md From 2e4480c4c8dbfb97afa72ca478803c64d5d69f88 Mon Sep 17 00:00:00 2001 From: Sasha Alex Romanenko Date: Wed, 15 Aug 2018 18:59:51 -0400 Subject: [PATCH 12/18] Optional: use PSR style error messages for files uploads. --- src/File/Upload.php | 17 +++++++++-------- src/File/UploadFile.php | 21 +++++++++++---------- test/File/UploadTest.php | 13 ++++++++----- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/File/Upload.php b/src/File/Upload.php index 4c1dc45cf..92d845969 100644 --- a/src/File/Upload.php +++ b/src/File/Upload.php @@ -38,13 +38,14 @@ class Upload extends AbstractValidator * @var array Error message templates */ protected $messageTemplates = [ - self::INI_SIZE => "File '%value%' exceeds the defined ini size", - self::FORM_SIZE => "File '%value%' exceeds the defined form size", + self::INI_SIZE => "File '%value%' exceeds upload_max_filesize directive in php.ini", + self::FORM_SIZE => "File '%value%' exceeds the MAX_FILE_SIZE directive that was " + . 'specified in the HTML form', self::PARTIAL => "File '%value%' was only partially uploaded", self::NO_FILE => "File '%value%' was not uploaded", - self::NO_TMP_DIR => "No temporary directory was found for file '%value%'", - self::CANT_WRITE => "File '%value%' can't be written", - self::EXTENSION => "A PHP extension returned an error while uploading the file '%value%'", + self::NO_TMP_DIR => "Missing a temporary folder to store '%value%'", + self::CANT_WRITE => "Failed to write file '%value%' to disk", + self::EXTENSION => "A PHP extension stopped uploading the file '%value%'", self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack", self::FILE_NOT_FOUND => "File '%value%' was not found", self::UNKNOWN => "Unknown error while uploading file '%value%'" @@ -89,10 +90,10 @@ public function getFiles($file = null) } if ($content instanceof UploadedFileInterface) { - if($content->getClientFilename() === $file) { + if ($content->getClientFilename() === $file) { $return[$name] = $this->options['files'][$name]; } - } else if ($content['name'] === $file) { + } elseif ($content['name'] === $file) { $return[$name] = $this->options['files'][$name]; } } @@ -129,7 +130,7 @@ public function setFiles($files = []) } foreach ($this->options['files'] as $file => $content) { - if (!($content instanceof UploadedFileInterface) && ! isset($content['error'])) { + if (! ($content instanceof UploadedFileInterface) && ! isset($content['error'])) { unset($this->options['files'][$file]); } } diff --git a/src/File/UploadFile.php b/src/File/UploadFile.php index 74ff28c83..32d529580 100644 --- a/src/File/UploadFile.php +++ b/src/File/UploadFile.php @@ -36,16 +36,17 @@ class UploadFile extends AbstractValidator * @var array Error message templates */ protected $messageTemplates = [ - self::INI_SIZE => "File exceeds the defined ini size", - self::FORM_SIZE => "File exceeds the defined form size", - self::PARTIAL => "File was only partially uploaded", - self::NO_FILE => "File was not uploaded", - self::NO_TMP_DIR => "No temporary directory was found for file", - self::CANT_WRITE => "File can't be written", - self::EXTENSION => "A PHP extension returned an error while uploading the file", - self::ATTACK => "File was illegally uploaded. This could be a possible attack", - self::FILE_NOT_FOUND => "File was not found", - self::UNKNOWN => "Unknown error while uploading file", + self::INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini', + self::FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was ' + . 'specified in the HTML form', + self::PARTIAL => 'The uploaded file was only partially uploaded', + self::NO_FILE => 'No file was uploaded', + self::NO_TMP_DIR => 'Missing a temporary folder', + self::CANT_WRITE => 'Failed to write file to disk', + self::EXTENSION => 'A PHP extension stopped the file upload', + self::ATTACK => 'File was illegally uploaded. This could be a possible attack', + self::FILE_NOT_FOUND => 'File was not found', + self::UNKNOWN => 'Unknown error while uploading file', ]; /** diff --git a/test/File/UploadTest.php b/test/File/UploadTest.php index 39bf3edab..e67e1ca08 100644 --- a/test/File/UploadTest.php +++ b/test/File/UploadTest.php @@ -290,7 +290,8 @@ public function testGetFiles() $this->assertEquals([], $validator->getFiles('test5')); } - public function testPsrGetFiles() { + public function testPsrGetFiles() + { $files = [ 'test' => new UploadedFile( 'tmp_test1', @@ -358,7 +359,8 @@ public function testSetFiles() $this->assertEquals($files, $validator->getFiles()); } - public function testPsrSetFiles() { + public function testPsrSetFiles() + { $psrFiles = [ 'test4' => new UploadedFile( 'tmp_test4', @@ -433,7 +435,7 @@ public function testErrorMessage() $this->assertEquals( [ - 'fileUploadErrorCantWrite' => "File 'bar' can't be written", + 'fileUploadErrorCantWrite' => "Failed to write file 'bar' to disk", ], $validator->getMessages() ); @@ -442,7 +444,8 @@ public function testErrorMessage() /** * @group ZF-12128 */ - public function testPsrErrorMessage() { + public function testPsrErrorMessage() + { $files = [ 'foo' => new UploadedFile( 'tmp_bar', @@ -459,7 +462,7 @@ public function testPsrErrorMessage() { $this->assertEquals( [ - 'fileUploadErrorCantWrite' => "File 'bar' can't be written", + 'fileUploadErrorCantWrite' => "Failed to write file 'bar' to disk", ], $validator->getMessages() ); From 2e07d223e5a0bfb30e76f05c6555335480dcca40 Mon Sep 17 00:00:00 2001 From: Sasha Alex Romanenko Date: Fri, 17 Aug 2018 08:08:41 -0400 Subject: [PATCH 13/18] Use PSR message in require. --- composer.json | 4 +- composer.lock | 102 +++++++++++++++++++++++++------------------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/composer.json b/composer.json index ec0a26964..28bfe7d7a 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "require": { "php": "^5.6 || ^7.0", "zendframework/zend-stdlib": "^2.7.6 || ^3.1", - "container-interop/container-interop": "^1.1" + "container-interop/container-interop": "^1.1", + "psr/http-message": "^1.0" }, "require-dev": { "zendframework/zend-cache": "^2.6.1", @@ -30,7 +31,6 @@ "zendframework/zend-uri": "^2.5", "phpunit/PHPUnit": "^6.0.8 || ^5.7.15", "zendframework/zend-coding-standard": "~1.0.0", - "psr/http-message": "^1.0", "zendframework/zend-diactoros": "^1.8" }, "suggest": { diff --git a/composer.lock b/composer.lock index fd9b214f9..672bec318 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3cfd67f8701bfaeb36e59c6affad0453", + "content-hash": "970553e35e01420e47166cc1347ede6b", "packages": [ { "name": "container-interop/container-interop", @@ -86,6 +86,56 @@ ], "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, { "name": "zendframework/zend-stdlib", "version": "3.1.0", @@ -828,56 +878,6 @@ ], "time": "2016-12-08T20:27:08+00:00" }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" - }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.1", From 935e772f9531ad22649217b08ecbf4064dd3165d Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 13 Dec 2018 11:28:29 -0600 Subject: [PATCH 14/18] Refactor PSR-7 support - Removes zend-diactoros from requirements. - Updates tests to use mock `UploadedFileInterface` instances, instead of using zend-diactoros; this keeps the support agnostic. - Modifies `UploadFile` to store the `UploadedFileInterface` instance instead of the stream URI; this is more consistent with the implementation of `Upload`, which stores an array of `UploadedFileInterface` instances. - The detection of an attack is moot with PSR-7, as it stores the uploaded file as an in-memory stream. As such, I modified both classes to omit that check; if we get an `UPLOAD_ERR_OK`, we have a valid upload at that point. - I extracted three methods from `UploadFile::isValid()`: - `validateFileFromErrorCode()` does a switch around the error code, setting errors and returning a boolean. - `validateUploadedFile()` is used in both the string and array value cases of `isValid()` to validate the incoming file. If `UPLOAD_ERR_OK` is detected, it performs additional logic to detect an upload attack, but otherwise delegates to `validateFileFromErrorCode()`. - `validatePsr7UploadedFile()` is used when the value is an `UploadedFileInterface`, and delegates to `validateFileFromErrorCode()`, using the result of `getError()`. - I refactored the new unit tests to use data providers whenever possible. --- composer.json | 13 +- composer.lock | 1197 ++++++++++++++++++++-------------- src/File/Upload.php | 21 +- src/File/UploadFile.php | 97 ++- test/File/UploadFileTest.php | 28 +- test/File/UploadTest.php | 268 ++++---- 6 files changed, 918 insertions(+), 706 deletions(-) diff --git a/composer.json b/composer.json index 28bfe7d7a..bffa84135 100644 --- a/composer.json +++ b/composer.json @@ -15,11 +15,13 @@ "require": { "php": "^5.6 || ^7.0", "zendframework/zend-stdlib": "^2.7.6 || ^3.1", - "container-interop/container-interop": "^1.1", - "psr/http-message": "^1.0" + "container-interop/container-interop": "^1.1" }, "require-dev": { + "phpunit/PHPUnit": "^6.0.8 || ^5.7.15", + "psr/http-message": "^1.0", "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", "zendframework/zend-db": "^2.7", "zendframework/zend-filter": "^2.6", @@ -28,13 +30,10 @@ "zendframework/zend-math": "^2.6", "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", "zendframework/zend-session": "^2.8", - "zendframework/zend-uri": "^2.5", - "phpunit/PHPUnit": "^6.0.8 || ^5.7.15", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-diactoros": "^1.8" + "zendframework/zend-uri": "^2.5" }, "suggest": { - "psr/http-message": "Zend\\Filter component, required by PsrFileInput validator", + "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators", "zendframework/zend-db": "Zend\\Db component, required by the (No)RecordExists validator", "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages", diff --git a/composer.lock b/composer.lock index 672bec318..59a733a6e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "970553e35e01420e47166cc1347ede6b", + "content-hash": "ad99d8812f502736c10c2285a57b1cbf", "packages": [ { "name": "container-interop/container-interop", @@ -86,83 +86,33 @@ ], "time": "2017-02-14T16:28:37+00:00" }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" - }, { "name": "zendframework/zend-stdlib", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78" + "reference": "66536006722aff9e62d1b331025089b7ec71c065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/debedcfc373a293f9250cc9aa03cf121428c8e78", - "reference": "debedcfc373a293f9250cc9aa03cf121428c8e78", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/66536006722aff9e62d1b331025089b7ec71c065", + "reference": "66536006722aff9e62d1b331025089b7ec71c065", "shasum": "" }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { - "athletic/athletic": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "^2.6.2" + "phpbench/phpbench": "^0.13", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" } }, "autoload": { @@ -174,43 +124,44 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-stdlib", + "description": "SPL extensions, array utilities, error handlers, and more", "keywords": [ + "ZendFramework", "stdlib", - "zf2" + "zf" ], - "time": "2016-09-13T14:38:50+00:00" + "time": "2018-08-28T21:34:05+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.0.5", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": "^7.1" }, "require-dev": { "athletic/athletic": "~0.1.8", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -235,41 +186,47 @@ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2017-07-22T11:58:36+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.6.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe" + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe", - "reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" }, "require-dev": { - "doctrine/collections": "1.*", - "phpunit/phpunit": "~4.1" + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" - } + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Create deep copies (clones) of your objects", - "homepage": "https://github.com/myclabs/DeepCopy", "keywords": [ "clone", "copy", @@ -277,20 +234,122 @@ "object", "object graph" ], - "time": "2017-01-26T22:05:40+00:00" + "time": "2018-06-11T23:09:50+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", - "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", "shasum": "" }, "require": { @@ -331,33 +390,39 @@ "reflection", "static analysis" ], - "time": "2015-12-27T11:43:31+00:00" + "time": "2017-09-11T18:02:19+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.1.1", + "version": "4.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", "shasum": "" }, "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.2.0", + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, "autoload": { "psr-4": { "phpDocumentor\\Reflection\\": [ @@ -376,24 +441,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-09-30T07:12:33+00:00" + "time": "2017-11-30T07:14:17+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.2.1", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "" }, "require": { - "php": ">=5.5", + "php": "^5.5 || ^7.0", "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { @@ -423,37 +488,37 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-11-25T06:54:22+00:00" + "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.7.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", - "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "sebastian/comparator": "^1.1|^2.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8 || ^5.6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { @@ -486,44 +551,44 @@ "spy", "stub" ], - "time": "2017-03-02T20:05:34+00:00" + "time": "2018-08-05T17:53:17+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.7", + "version": "5.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "09e2277d14ea467e5a984010f501343ef29ffc69" + "reference": "c89677919c5dd6d3b3852f230a663118762218ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09e2277d14ea467e5a984010f501343ef29ffc69", - "reference": "09e2277d14ea467e5a984010f501343ef29ffc69", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", + "reference": "c89677919c5dd6d3b3852f230a663118762218ac", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^5.6 || ^7.0", - "phpunit/php-file-iterator": "^1.3", - "phpunit/php-text-template": "^1.2", - "phpunit/php-token-stream": "^1.4.2 || ^2.0", - "sebastian/code-unit-reverse-lookup": "^1.0", - "sebastian/environment": "^1.3.2 || ^2.0", - "sebastian/version": "^1.0 || ^2.0" + "php": "^7.0", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^2.0.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" }, "require-dev": { - "ext-xdebug": "^2.1.4", - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^6.0" }, "suggest": { - "ext-xdebug": "^2.5.1" + "ext-xdebug": "^2.5.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "5.3.x-dev" } }, "autoload": { @@ -538,7 +603,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -549,20 +614,20 @@ "testing", "xunit" ], - "time": "2017-03-01T09:12:17+00:00" + "time": "2018-04-06T15:36:58+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.2", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", - "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", "shasum": "" }, "require": { @@ -596,7 +661,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03T07:40:28+00:00" + "time": "2017-11-27T13:52:08+00:00" }, { "name": "phpunit/php-text-template", @@ -690,29 +755,29 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.11", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" + "reference": "791198a2c6254db10131eecfe8c06670700904db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", - "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", + "reference": "791198a2c6254db10131eecfe8c06670700904db", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.2.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -735,20 +800,20 @@ "keywords": [ "tokenizer" ], - "time": "2017-02-27T10:12:30+00:00" + "time": "2017-11-27T05:48:46+00:00" }, { "name": "phpunit/phpunit", - "version": "5.7.16", + "version": "6.5.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "dafc78e2a7d12139b0e97078d1082326bd09363d" + "reference": "0973426fb012359b2f18d3bd1e90ef1172839693" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/dafc78e2a7d12139b0e97078d1082326bd09363d", - "reference": "dafc78e2a7d12139b0e97078d1082326bd09363d", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0973426fb012359b2f18d3bd1e90ef1172839693", + "reference": "0973426fb012359b2f18d3bd1e90ef1172839693", "shasum": "" }, "require": { @@ -757,33 +822,35 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "~1.3", - "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.6.2", - "phpunit/php-code-coverage": "^4.0.4", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "^1.2.4", - "sebastian/diff": "~1.2", - "sebastian/environment": "^1.3.4 || ^2.0", - "sebastian/exporter": "~2.0", - "sebastian/global-state": "^1.1", - "sebastian/object-enumerator": "~2.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "~1.0.3|~2.0", - "symfony/yaml": "~2.1|~3.0" + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.0", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^5.3", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^1.0.9", + "phpunit/phpunit-mock-objects": "^5.0.9", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^2.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" }, "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2" + "phpdocumentor/reflection-docblock": "3.0.2", + "phpunit/dbunit": "<3.0" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-xdebug": "*", - "phpunit/php-invoker": "~1.1" + "phpunit/php-invoker": "^1.1" }, "bin": [ "phpunit" @@ -791,7 +858,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.7.x-dev" + "dev-master": "6.5.x-dev" } }, "autoload": { @@ -817,33 +884,33 @@ "testing", "xunit" ], - "time": "2017-03-15T13:02:34+00:00" + "time": "2018-09-08T15:10:43+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.4.3", + "version": "5.0.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", - "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", + "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.6 || ^7.0", - "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2 || ^2.0" + "doctrine/instantiator": "^1.0.5", + "php": "^7.0", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" }, "conflict": { - "phpunit/phpunit": "<5.4.0" + "phpunit/phpunit": "<6.0" }, "require-dev": { - "phpunit/phpunit": "^5.4" + "phpunit/phpunit": "^6.5.11" }, "suggest": { "ext-soap": "*" @@ -851,7 +918,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "5.0.x-dev" } }, "autoload": { @@ -866,7 +933,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -876,7 +943,151 @@ "mock", "xunit" ], - "time": "2016-12-08T20:27:08+00:00" + "time": "2018-08-09T05:50:03+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -925,30 +1136,30 @@ }, { "name": "sebastian/comparator", - "version": "1.2.4", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.1.x-dev" } }, "autoload": { @@ -979,38 +1190,38 @@ } ], "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", + "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], - "time": "2017-01-29T09:50:25+00:00" + "time": "2018-02-01T13:46:46+00:00" }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^6.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1037,32 +1248,32 @@ "keywords": [ "diff" ], - "time": "2015-12-08T07:14:41+00:00" + "time": "2017-08-03T08:09:46+00:00" }, { "name": "sebastian/environment", - "version": "2.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1087,34 +1298,34 @@ "environment", "hhvm" ], - "time": "2016-11-26T07:53:53+00:00" + "time": "2017-07-01T08:51:00+00:00" }, { "name": "sebastian/exporter", - "version": "2.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~2.0" + "php": "^7.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1154,27 +1365,27 @@ "export", "exporter" ], - "time": "2016-11-19T08:54:04+00:00" + "time": "2017-04-03T13:19:02+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" @@ -1182,7 +1393,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1205,33 +1416,34 @@ "keywords": [ "global state" ], - "time": "2015-10-12T03:26:01+00:00" + "time": "2017-04-27T15:39:26+00:00" }, { "name": "sebastian/object-enumerator", - "version": "2.0.1", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/recursion-context": "~2.0" + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1251,32 +1463,77 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-02-18T15:18:39+00:00" + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" }, { "name": "sebastian/recursion-context", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1304,7 +1561,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-11-19T07:33:16+00:00" + "time": "2017-03-03T06:23:57+00:00" }, { "name": "sebastian/resource-operations", @@ -1393,16 +1650,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "2.8.1", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d" + "reference": "2acf168de78487db620ab4bc524135a13cfe6745" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", - "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", + "reference": "2acf168de78487db620ab4bc524135a13cfe6745", "shasum": "" }, "require": { @@ -1467,75 +1724,60 @@ "phpcs", "standards" ], - "time": "2017-03-01T22:17:45+00:00" + "time": "2018-11-07T22:31:41+00:00" }, { - "name": "symfony/yaml", - "version": "v3.2.6", + "name": "theseer/tokenizer", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a" + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/093e416ad096355149e265ea2e4cc1f9ee40ab1a", - "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", "shasum": "" }, "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "symfony/console": "~2.8|~3.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2017-03-07T16:47:02+00:00" + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" }, { "name": "webmozart/assert", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", "shasum": "" }, "require": { @@ -1572,34 +1814,41 @@ "check", "validate" ], - "time": "2016-11-23T20:04:58+00:00" + "time": "2018-01-29T19:49:41+00:00" }, { "name": "zendframework/zend-cache", - "version": "2.7.2", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-cache.git", - "reference": "c98331b96d3b9d9b24cf32d02660602edb34d039" + "reference": "4983dff629956490c78b88adcc8ece4711d7d8a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-cache/zipball/c98331b96d3b9d9b24cf32d02660602edb34d039", - "reference": "c98331b96d3b9d9b24cf32d02660602edb34d039", + "url": "https://api.github.com/repos/zendframework/zend-cache/zipball/4983dff629956490c78b88adcc8ece4711d7d8a3", + "reference": "4983dff629956490c78b88adcc8ece4711d7d8a3", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-stdlib": "^2.7 || ^3.0" + "php": "^5.6 || ^7.0", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "zendframework/zend-eventmanager": "^2.6.3 || ^3.2", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.3", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0" }, "require-dev": { - "phpbench/phpbench": "^0.10.0", - "phpunit/phpunit": "^4.8", + "cache/integration-tests": "^0.16", + "phpbench/phpbench": "^0.13", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-serializer": "^2.6", - "zendframework/zend-session": "^2.6.2" + "zendframework/zend-session": "^2.7.4" }, "suggest": { "ext-apc": "APC or compatible extension, to use the APC storage adapter", @@ -1608,9 +1857,11 @@ "ext-memcache": "Memcache >= 2.0.0 to use the Memcache storage adapter", "ext-memcached": "Memcached >= 1.0.0 to use the Memcached storage adapter", "ext-mongo": "Mongo, to use MongoDb storage adapter", + "ext-mongodb": "MongoDB, to use the ExtMongoDb storage adapter", "ext-redis": "Redis, to use Redis storage adapter", "ext-wincache": "WinCache, to use the WinCache storage adapter", "ext-xcache": "XCache, to use the XCache storage adapter", + "mongodb/mongodb": "Required for use with the ext-mongodb adapter", "mongofill/mongofill": "Alternative to ext-mongo - a pure PHP implementation designed as a drop in replacement", "zendframework/zend-serializer": "Zend\\Serializer component", "zendframework/zend-session": "Zend\\Session component" @@ -1618,8 +1869,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "2.8.x-dev", + "dev-develop": "2.9.x-dev" }, "zf": { "component": "Zend\\Cache", @@ -1627,6 +1878,9 @@ } }, "autoload": { + "files": [ + "autoload/patternPluginManagerPolyfill.php" + ], "psr-4": { "Zend\\Cache\\": "src/" } @@ -1635,13 +1889,15 @@ "license": [ "BSD-3-Clause" ], - "description": "provides a generic way to cache any data", - "homepage": "https://github.com/zendframework/zend-cache", + "description": "Caching implementation with a variety of storage options, as well as codified caching strategies for callbacks, classes, and output", "keywords": [ + "ZendFramework", "cache", - "zf2" + "psr-16", + "psr-6", + "zf" ], - "time": "2016-12-16T11:35:47+00:00" + "time": "2018-05-01T21:58:00+00:00" }, { "name": "zendframework/zend-coding-standard", @@ -1730,25 +1986,25 @@ }, { "name": "zendframework/zend-db", - "version": "2.8.2", + "version": "2.9.3", "source": { "type": "git", "url": "https://github.com/zendframework/zend-db.git", - "reference": "5926a1a2e7e035546b690cb7d4c11a3c47db2c98" + "reference": "5b4f2c42f94c9f7f4b2f456a0ebe459fab12b3d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-db/zipball/5926a1a2e7e035546b690cb7d4c11a3c47db2c98", - "reference": "5926a1a2e7e035546b690cb7d4c11a3c47db2c98", + "url": "https://api.github.com/repos/zendframework/zend-db/zipball/5b4f2c42f94c9f7f4b2f456a0ebe459fab12b3d9", + "reference": "5b4f2c42f94c9f7f4b2f456a0ebe459fab12b3d9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", + "php": "^5.6 || ^7.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", + "phpunit/phpunit": "^5.7.25 || ^6.4.4", + "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", "zendframework/zend-hydrator": "^1.1 || ^2.1", "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3" @@ -1761,8 +2017,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" + "dev-master": "2.9-dev", + "dev-develop": "2.10-dev" }, "zf": { "component": "Zend\\Db", @@ -1778,102 +2034,40 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-db", + "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", "keywords": [ + "ZendFramework", "db", - "zf2" - ], - "time": "2016-08-09T19:28:55+00:00" - }, - { - "name": "zendframework/zend-diactoros", - "version": "1.8.5", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/3e4edb822c942f37ade0d09579cfbab11e2fee87", - "reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0", - "psr/http-message": "^1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-dom": "*", - "ext-libxml": "*", - "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7", - "zendframework/zend-coding-standard": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev", - "dev-develop": "1.9.x-dev", - "dev-release-2.0": "2.0.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions/create_uploaded_file.php", - "src/functions/marshal_headers_from_sapi.php", - "src/functions/marshal_method_from_sapi.php", - "src/functions/marshal_protocol_version_from_sapi.php", - "src/functions/marshal_uri_from_sapi.php", - "src/functions/normalize_server.php", - "src/functions/normalize_uploaded_files.php", - "src/functions/parse_cookie_header.php" - ], - "psr-4": { - "Zend\\Diactoros\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "PSR HTTP Message implementations", - "homepage": "https://github.com/zendframework/zend-diactoros", - "keywords": [ - "http", - "psr", - "psr-7" + "zf" ], - "time": "2018-08-10T14:16:32+00:00" + "time": "2018-04-09T13:21:36+00:00" }, { "name": "zendframework/zend-escaper", - "version": "2.5.2", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e" + "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/2dcd14b61a72d8b8e27d579c6344e12c26141d4e", - "reference": "2dcd14b61a72d8b8e27d579c6344e12c26141d4e", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/31d8aafae982f9568287cb4dce987e6aff8fd074", + "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^5.6 || ^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -1885,25 +2079,26 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-escaper", + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", "keywords": [ + "ZendFramework", "escaper", - "zf2" + "zf" ], - "time": "2016-06-30T19:48:38+00:00" + "time": "2018-04-25T15:48:53+00:00" }, { "name": "zendframework/zend-eventmanager", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "c3bce7b7d47c54040b9ae51bc55491c72513b75d" + "reference": "a5e2583a211f73604691586b8406ff7296a946dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/c3bce7b7d47c54040b9ae51bc55491c72513b75d", - "reference": "c3bce7b7d47c54040b9ae51bc55491c72513b75d", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd", + "reference": "a5e2583a211f73604691586b8406ff7296a946dd", "shasum": "" }, "require": { @@ -1912,7 +2107,7 @@ "require-dev": { "athletic/athletic": "^0.1", "container-interop/container-interop": "^1.1.0", - "phpunit/phpunit": "^5.6", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-stdlib": "^2.7.3 || ^3.0" }, @@ -1923,8 +2118,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev", - "dev-develop": "3.2-dev" + "dev-master": "3.2-dev", + "dev-develop": "3.3-dev" } }, "autoload": { @@ -1944,35 +2139,40 @@ "events", "zf2" ], - "time": "2016-12-19T21:47:12+00:00" + "time": "2018-04-25T15:33:34+00:00" }, { "name": "zendframework/zend-filter", - "version": "2.7.1", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-filter.git", - "reference": "84c50246428efb0a1e52868e162dab3e149d5b80" + "reference": "875da9790e5cb16b9a12f41453d5f7c441452daf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/84c50246428efb0a1e52868e162dab3e149d5b80", - "reference": "84c50246428efb0a1e52868e162dab3e149d5b80", + "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/875da9790e5cb16b9a12f41453d5f7c441452daf", + "reference": "875da9790e5cb16b9a12f41453d5f7c441452daf", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" + "php": "^5.6 || ^7.0", + "zendframework/zend-stdlib": "^2.7.7 || ^3.1" + }, + "conflict": { + "zendframework/zend-validator": "<2.10.1" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "pear/archive_tar": "^1.4", - "phpunit/phpunit": "~4.0", - "zendframework/zend-crypt": "^2.6", - "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", - "zendframework/zend-uri": "^2.5" + "pear/archive_tar": "^1.4.3", + "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "psr/http-factory": "^1.0", + "zendframework/zend-coding-standard": "~1.0.0", + "zendframework/zend-crypt": "^3.2.1", + "zendframework/zend-servicemanager": "^2.7.8 || ^3.3", + "zendframework/zend-uri": "^2.6" }, "suggest": { + "psr/http-factory-implementation": "psr/http-factory-implementation, for creating file upload instances when consuming PSR-7 in file upload filters", "zendframework/zend-crypt": "Zend\\Crypt component, for encryption filters", "zendframework/zend-i18n": "Zend\\I18n component for filters depending on i18n functionality", "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for using the filter chain functionality", @@ -1981,8 +2181,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "2.9.x-dev", + "dev-develop": "2.10.x-dev" }, "zf": { "component": "Zend\\Filter", @@ -1999,44 +2199,47 @@ "BSD-3-Clause" ], "description": "provides a set of commonly needed data filters", - "homepage": "https://github.com/zendframework/zend-filter", "keywords": [ + "ZendFramework", "filter", - "zf2" + "zf" ], - "time": "2016-04-18T18:32:43+00:00" + "time": "2018-12-12T23:14:25+00:00" }, { "name": "zendframework/zend-http", - "version": "2.6.0", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-http.git", - "reference": "09f4d279f46d86be63171ff62ee0f79eca878678" + "reference": "2c8aed3d25522618573194e7cc51351f8cd4a45b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-http/zipball/09f4d279f46d86be63171ff62ee0f79eca878678", - "reference": "09f4d279f46d86be63171ff62ee0f79eca878678", + "url": "https://api.github.com/repos/zendframework/zend-http/zipball/2c8aed3d25522618573194e7cc51351f8cd4a45b", + "reference": "2c8aed3d25522618573194e7cc51351f8cd4a45b", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "zendframework/zend-loader": "^2.5", - "zendframework/zend-stdlib": "^2.5 || ^3.0", - "zendframework/zend-uri": "^2.5", - "zendframework/zend-validator": "^2.5" + "php": "^5.6 || ^7.0", + "zendframework/zend-loader": "^2.5.1", + "zendframework/zend-stdlib": "^3.1 || ^2.7.7", + "zendframework/zend-uri": "^2.5.2", + "zendframework/zend-validator": "^2.10.1" }, "require-dev": { - "phpunit/phpunit": "^4.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.3", "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-config": "^2.5" + "zendframework/zend-config": "^3.1 || ^2.6" + }, + "suggest": { + "paragonie/certainty": "For automated management of cacert.pem" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" + "dev-master": "2.8.x-dev", + "dev-develop": "2.9.x-dev" } }, "autoload": { @@ -2048,36 +2251,38 @@ "license": [ "BSD-3-Clause" ], - "description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", - "homepage": "https://github.com/zendframework/zend-http", + "description": "Provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests", "keywords": [ + "ZendFramework", "http", - "zf2" + "http client", + "zend", + "zf" ], - "time": "2017-01-31T14:41:02+00:00" + "time": "2018-08-13T18:47:03+00:00" }, { "name": "zendframework/zend-i18n", - "version": "2.7.3", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-i18n.git", - "reference": "b2db0d8246a865c659f93199f90f5fc2cd2f3cd8" + "reference": "6d69af5a04e1a4de7250043cb1322f077a0cdb7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/b2db0d8246a865c659f93199f90f5fc2cd2f3cd8", - "reference": "b2db0d8246a865c659f93199f90f5fc2cd2f3cd8", + "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/6d69af5a04e1a4de7250043cb1322f077a0cdb7f", + "reference": "6d69af5a04e1a4de7250043cb1322f077a0cdb7f", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", + "php": "^5.6 || ^7.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", "zendframework/zend-filter": "^2.6.1", @@ -2099,8 +2304,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev", - "dev-develop": "2.8-dev" + "dev-master": "2.9.x-dev", + "dev-develop": "2.10.x-dev" }, "zf": { "component": "Zend\\I18n", @@ -2116,39 +2321,40 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-i18n", + "description": "Provide translations for your application, and filter and validate internationalized values", "keywords": [ + "ZendFramework", "i18n", - "zf2" + "zf" ], - "time": "2016-06-07T21:08:30+00:00" + "time": "2018-05-16T16:39:13+00:00" }, { "name": "zendframework/zend-loader", - "version": "2.5.1", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-loader.git", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c" + "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c", - "reference": "c5fd2f071bde071f4363def7dea8dec7393e135c", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/78f11749ea340f6ca316bca5958eef80b38f9b6c", + "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": "^5.6 || ^7.0" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -2160,25 +2366,26 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-loader", + "description": "Autoloading and plugin loading strategies", "keywords": [ + "ZendFramework", "loader", - "zf2" + "zf" ], - "time": "2015-06-03T14:05:47+00:00" + "time": "2018-04-30T15:20:54+00:00" }, { "name": "zendframework/zend-math", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-math.git", - "reference": "f4358090d5d23973121f1ed0b376184b66d9edec" + "reference": "1abce074004dacac1a32cd54de94ad47ef960d38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-math/zipball/f4358090d5d23973121f1ed0b376184b66d9edec", - "reference": "f4358090d5d23973121f1ed0b376184b66d9edec", + "url": "https://api.github.com/repos/zendframework/zend-math/zipball/1abce074004dacac1a32cd54de94ad47ef960d38", + "reference": "1abce074004dacac1a32cd54de94ad47ef960d38", "shasum": "" }, "require": { @@ -2215,20 +2422,20 @@ "math", "zf2" ], - "time": "2016-04-07T16:29:53+00:00" + "time": "2018-12-04T15:34:17+00:00" }, { "name": "zendframework/zend-servicemanager", - "version": "3.3.0", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-servicemanager.git", - "reference": "c3036efb81f71bfa36cc9962ee5d4474f36581d0" + "reference": "9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/c3036efb81f71bfa36cc9962ee5d4474f36581d0", - "reference": "c3036efb81f71bfa36cc9962ee5d4474f36581d0", + "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42", + "reference": "9f35a104b8d4d3b32da5f4a3b6efc0dd62e5af42", "shasum": "" }, "require": { @@ -2242,10 +2449,10 @@ "psr/container-implementation": "^1.0" }, "require-dev": { - "mikey179/vfsstream": "^1.6", + "mikey179/vfsstream": "^1.6.5", "ocramius/proxy-manager": "^1.0 || ^2.0", - "phpbench/phpbench": "^0.10.0", - "phpunit/phpunit": "^5.7 || ^6.0.6", + "phpbench/phpbench": "^0.13.0", + "phpunit/phpunit": "^5.7.25 || ^6.4.4", "zendframework/zend-coding-standard": "~1.0.0" }, "suggest": { @@ -2260,7 +2467,7 @@ "extra": { "branch-alias": { "dev-master": "3.3-dev", - "dev-develop": "3.4-dev" + "dev-develop": "4.0-dev" } }, "autoload": { @@ -2272,37 +2479,43 @@ "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zend-servicemanager", + "description": "Factory-Driven Dependency Injection Container", "keywords": [ + "PSR-11", + "ZendFramework", + "dependency-injection", + "di", + "dic", "service-manager", "servicemanager", "zf" ], - "time": "2017-03-01T22:08:02+00:00" + "time": "2018-01-29T16:48:37+00:00" }, { "name": "zendframework/zend-session", - "version": "2.8.0", + "version": "2.8.5", "source": { "type": "git", "url": "https://github.com/zendframework/zend-session.git", - "reference": "b1486c382decc241de8b1c7778eaf2f0a884f67d" + "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-session/zipball/b1486c382decc241de8b1c7778eaf2f0a884f67d", - "reference": "b1486c382decc241de8b1c7778eaf2f0a884f67d", + "url": "https://api.github.com/repos/zendframework/zend-session/zipball/2cfd90e1a2f6b066b9f908599251d8f64f07021b", + "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b", "shasum": "" }, "require": { - "php": "^7.0 || ^5.6", + "php": "^5.6 || ^7.0", "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { "container-interop/container-interop": "^1.1", "mongodb/mongodb": "^1.0.1", - "phpunit/phpunit": "^6.0.8 || ^5.7.15", + "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", + "phpunit/phpunit": "^5.7.5 || >=6.0.13 <6.5.0", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-db": "^2.7", @@ -2339,41 +2552,41 @@ "BSD-3-Clause" ], "description": "manage and preserve session data, a logical complement of cookie data, across multiple page requests by the same client", - "homepage": "https://github.com/zendframework/zend-session", "keywords": [ + "ZendFramework", "session", - "zf2" + "zf" ], - "time": "2017-06-19T21:31:39+00:00" + "time": "2018-02-22T16:33:54+00:00" }, { "name": "zendframework/zend-uri", - "version": "2.5.2", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-uri.git", - "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed" + "reference": "3b6463645c6766f78ce537c70cb4fdabee1e725f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/0bf717a239432b1a1675ae314f7c4acd742749ed", - "reference": "0bf717a239432b1a1675ae314f7c4acd742749ed", + "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/3b6463645c6766f78ce537c70cb4fdabee1e725f", + "reference": "3b6463645c6766f78ce537c70cb4fdabee1e725f", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", + "php": "^5.6 || ^7.0", "zendframework/zend-escaper": "^2.5", - "zendframework/zend-validator": "^2.5" + "zendframework/zend-validator": "^2.10" }, "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.4", + "zendframework/zend-coding-standard": "~1.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" } }, "autoload": { @@ -2385,13 +2598,13 @@ "license": [ "BSD-3-Clause" ], - "description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", - "homepage": "https://github.com/zendframework/zend-uri", + "description": "A component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)", "keywords": [ + "ZendFramework", "uri", - "zf2" + "zf" ], - "time": "2016-02-17T22:38:51+00:00" + "time": "2018-04-30T13:40:08+00:00" } ], "aliases": [], diff --git a/src/File/Upload.php b/src/File/Upload.php index 92d845969..76fd90f7a 100644 --- a/src/File/Upload.php +++ b/src/File/Upload.php @@ -130,7 +130,9 @@ public function setFiles($files = []) } foreach ($this->options['files'] as $file => $content) { - if (! ($content instanceof UploadedFileInterface) && ! isset($content['error'])) { + if (! $content instanceof UploadedFileInterface + && ! isset($content['error']) + ) { unset($this->options['files'][$file]); } } @@ -182,15 +184,20 @@ public function isValid($value, $file = null) foreach ($files as $file => $content) { $this->value = $file; - $error = ($content instanceof UploadedFileInterface) ? - $content->getError() : $content['error']; + $error = $content instanceof UploadedFileInterface + ? $content->getError() + : $content['error']; + switch ($error) { case 0: - $tmpFile = ($content instanceof UploadedFileInterface) ? - $content->getStream()->getMetadata('uri') : - $content['tmp_name']; + if ($content instanceof UploadedFileInterface) { + // done! + break; + } - if (! is_uploaded_file($tmpFile)) { + // For standard SAPI environments, check that the upload + // was valid + if (! is_uploaded_file($content['tmp_name'])) { $this->throwError($content, self::ATTACK); } break; diff --git a/src/File/UploadFile.php b/src/File/UploadFile.php index 32d529580..d3a647a1d 100644 --- a/src/File/UploadFile.php +++ b/src/File/UploadFile.php @@ -64,69 +64,106 @@ public function isValid($value) 'Value array must be in $_FILES format' ); } - $file = $value['tmp_name']; - $filename = $value['name']; - $error = $value['error']; - } elseif ($value instanceof UploadedFileInterface) { - /** @var UploadedFileInterface $value */ - $filename = $value->getClientFilename(); - $error = $value->getError(); - if (UPLOAD_ERR_OK === $error) { - $file = $value->getStream()->getMetadata('uri'); - } - } else { - $file = $value; - $filename = basename($file); - $error = 0; + + return $this->validateUploadedFile( + $value['error'], + $value['name'], + $value['tmp_name'] + ); } - $this->setValue($filename); + if ($value instanceof UploadedFileInterface) { + return $this->validatePsr7UploadedFile($value); + } + + if (is_string($value)) { + return $this->validateUploadedFile(0, basename($value), $value); + } + + $this->error(self::UNKNOWN); + return false; + } + + /** + * @param int $error UPLOAD_ERR_* constant value + * @return bool + */ + private function validateFileFromErrorCode($error) + { switch ($error) { case UPLOAD_ERR_OK: - if (empty($file) || false === is_file($file)) { - $this->error(self::FILE_NOT_FOUND); - } elseif (! is_uploaded_file($file)) { - $this->error(self::ATTACK); - } - break; + return true; case UPLOAD_ERR_INI_SIZE: $this->error(self::INI_SIZE); - break; + return false; case UPLOAD_ERR_FORM_SIZE: $this->error(self::FORM_SIZE); - break; + return false; case UPLOAD_ERR_PARTIAL: $this->error(self::PARTIAL); - break; + return false; case UPLOAD_ERR_NO_FILE: $this->error(self::NO_FILE); - break; + return false; case UPLOAD_ERR_NO_TMP_DIR: $this->error(self::NO_TMP_DIR); - break; + return false; case UPLOAD_ERR_CANT_WRITE: $this->error(self::CANT_WRITE); - break; + return false; case UPLOAD_ERR_EXTENSION: $this->error(self::EXTENSION); - break; + return false; default: $this->error(self::UNKNOWN); - break; + return false; } + } - if ($this->getMessages()) { + /** + * @param int $error UPLOAD_ERR_* constant + * @param string $filename + * @param string $uploadedFile Name of uploaded file (gen tmp_name) + * @return bool + */ + private function validateUploadedFile($error, $filename, $uploadedFile) + { + $this->setValue($filename); + + // Normal errors can be validated normally + if ($error !== UPLOAD_ERR_OK) { + return $this->validateFileFromErrorCode($error); + } + + // Did we get no name? Is the file missing? + if (empty($uploadedFile) || false === is_file($uploadedFile)) { + $this->error(self::FILE_NOT_FOUND); + return false; + } + + // Do we have an invalid upload? + if (! is_uploaded_file($uploadedFile)) { + $this->error(self::ATTACK); return false; } return true; } + + /** + * @return bool + */ + private function validatePsr7UploadedFile(UploadedFileInterface $uploadedFile) + { + $this->setValue($uploadedFile); + return $this->validateFileFromErrorCode($uploadedFile->getError()); + } } diff --git a/test/File/UploadFileTest.php b/test/File/UploadFileTest.php index 30ede1bfa..8ed1187f3 100644 --- a/test/File/UploadFileTest.php +++ b/test/File/UploadFileTest.php @@ -10,7 +10,7 @@ namespace ZendTest\Validator\File; use PHPUnit\Framework\TestCase; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; use Zend\Validator\Exception\InvalidArgumentException; use Zend\Validator\File; @@ -37,7 +37,8 @@ public function uploadErrorsTestDataProvider() $testSizeFile = __DIR__ . '/_files/testsize.mo'; foreach ($errorTypes as $errorCode => $errorType) { - $data[] = [ + $name = sprintf('SAPI - %s', $errorType); + $data[$name] = [ // fileInfo [ 'name' => 'test' . $errorCode, @@ -54,18 +55,19 @@ public function uploadErrorsTestDataProvider() // Diactoros does not have UNKNOWN error type. unset($errorTypes[9]); foreach ($errorTypes as $errorCode => $errorType) { - $data[] = [ - new UploadedFile( - // need a real file for Stream to not throw exceptions - $testSizeFile, - 200 + $errorCode, - $errorCode, - 'test' . $errorCode, - 'text' - ), - $errorType, - ]; + if ($errorCode === UPLOAD_ERR_OK) { + // Unable to get to this vector + continue; + } + + $name = sprintf('PSR-7 - %s', $errorType); + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test' . $errorCode); + $upload->getError()->willReturn($errorCode); + + $data[$name] = [$upload->reveal(), $errorType]; } + return $data; } diff --git a/test/File/UploadTest.php b/test/File/UploadTest.php index e67e1ca08..f5c5f3ebb 100644 --- a/test/File/UploadTest.php +++ b/test/File/UploadTest.php @@ -10,7 +10,7 @@ namespace ZendTest\Validator\File; use PHPUnit\Framework\TestCase; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; use Zend\Validator\Exception\InvalidArgumentException; use Zend\Validator\File; @@ -132,115 +132,98 @@ public function testBasic() $this->assertArrayHasKey('fileUploadErrorFileNotFound', $validator->getMessages()); } - /** - * Ensures that the validator follows expected behavior - * - * @return void - */ - public function testPsrBasic() + public function invalidPsr7UploadedFiles() { - $files = [ - 'test' => new UploadedFile( - __DIR__ . '/_files/testsize.mo', // has to be real file - 200, - 0, - 'test1', - 'text' - ), - 'test2' => new UploadedFile( - 'tmp_test2', - 202, - 1, - 'test2', - 'text2' - ), - 'test3' => new UploadedFile( - 'tmp_test3', - 203, - 2, - 'test3', - 'text3' - ), - 'test4' => new UploadedFile( - 'tmp_test4', - 204, - 3, - 'test4', - 'text4' - ), - 'test5' => new UploadedFile( - 'tmp_test5', - 205, - 4, - 'test5', - 'text5' - ), - 'test6' => new UploadedFile( - 'tmp_test6', - 206, - 5, - 'test6', - 'text6' - ), - 'test7' => new UploadedFile( - 'tmp_test7', - 207, - 6, - 'test7', - 'text7' - ), - 'test8' => new UploadedFile( - 'tmp_test8', - 208, - 7, - 'test8', - 'text8' - ), - 'test9' => new UploadedFile( - 'tmp_test9', - 209, - 8, - 'test9', - 'text9' - ) - ]; + $uploads = []; - $validator = new File\Upload(); - $validator->setFiles($files); - $this->assertFalse($validator->isValid('test')); - $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test2'); + $upload->getError()->willReturn(1); + yield 'size' => [['test2' => $upload->reveal()], 'test2', 'fileUploadErrorIniSize']; - $this->assertFalse($validator->isValid('test2')); - $this->assertArrayHasKey('fileUploadErrorIniSize', $validator->getMessages()); + $uploads['test2'] = $upload->reveal(); - $this->assertFalse($validator->isValid('test3')); - $this->assertArrayHasKey('fileUploadErrorFormSize', $validator->getMessages()); + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test3'); + $upload->getError()->willReturn(2); + yield 'form-size' => [['test3' => $upload->reveal()], 'test3', 'fileUploadErrorFormSize']; - $this->assertFalse($validator->isValid('test4')); - $this->assertArrayHasKey('fileUploadErrorPartial', $validator->getMessages()); + $uploads['test3'] = $upload->reveal(); - $this->assertFalse($validator->isValid('test5')); - $this->assertArrayHasKey('fileUploadErrorNoFile', $validator->getMessages()); + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test4'); + $upload->getError()->willReturn(3); + yield 'partial' => [['test4' => $upload->reveal()], 'test4', 'fileUploadErrorPartial']; - $this->assertFalse($validator->isValid('test6')); - $this->assertArrayHasKey('fileUploadErrorUnknown', $validator->getMessages()); + $uploads['test4'] = $upload->reveal(); - $this->assertFalse($validator->isValid('test7')); - $this->assertArrayHasKey('fileUploadErrorNoTmpDir', $validator->getMessages()); + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test5'); + $upload->getError()->willReturn(4); + yield 'no-file' => [['test5' => $upload->reveal()], 'test5', 'fileUploadErrorNoFile']; - $this->assertFalse($validator->isValid('test8')); - $this->assertArrayHasKey('fileUploadErrorCantWrite', $validator->getMessages()); + $uploads['test5'] = $upload->reveal(); - $this->assertFalse($validator->isValid('test9')); - $this->assertArrayHasKey('fileUploadErrorExtension', $validator->getMessages()); + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test6'); + $upload->getError()->willReturn(5); + yield 'unknown' => [['test6' => $upload->reveal()], 'test6', 'fileUploadErrorUnknown']; - $this->assertFalse($validator->isValid('test1')); - $this->assertArrayHasKey('fileUploadErrorAttack', $validator->getMessages()); + $uploads['test6'] = $upload->reveal(); - // not testing lookup by temp file name since PSR does not expose it + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test7'); + $upload->getError()->willReturn(6); + yield 'no-tmp-dir' => [['test7' => $upload->reveal()], 'test7', 'fileUploadErrorNoTmpDir']; - $this->assertFalse($validator->isValid('test000')); - $this->assertArrayHasKey('fileUploadErrorFileNotFound', $validator->getMessages()); + $uploads['test7'] = $upload->reveal(); + + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test8'); + $upload->getError()->willReturn(7); + yield 'cannot write' => [['test8' => $upload->reveal()], 'test8', 'fileUploadErrorCantWrite']; + + $uploads['test8'] = $upload->reveal(); + + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test9'); + $upload->getError()->willReturn(8); + yield 'cannot write' => [['test9' => $upload->reveal()], 'test9', 'fileUploadErrorExtension']; + + $uploads['test9'] = $upload->reveal(); + + yield 'not-found' => [$uploads, 'test000', 'fileUploadErrorFileNotFound']; + } + + /** + * Validate invalid PSR-7 file uploads + * + * Not testing lookup by temp file name since PSR does not expose it. + * + * @dataProvider invalidPsr7UploadedFiles + * @param UploadedFileInterface[] $files + * @param string $fileName + * @param string $expectedErrorKey + * @return void + */ + public function testRaisesExpectedErrorsForInvalidPsr7UploadedFileInput($files, $fileName, $expectedErrorKey) + { + $validator = new File\Upload(); + $validator->setFiles($files); + $this->assertFalse($validator->isValid($fileName)); + $this->assertArrayHasKey($expectedErrorKey, $validator->getMessages()); + } + + public function testCanValidateCorrectlyFormedPsr7UploadedFiles() + { + $upload = $this->prophesize(UploadedFileInterface::class); + $upload->getClientFilename()->willReturn('test'); + $upload->getError()->willReturn(0); + + $validator = new File\Upload(); + $validator->setFiles(['upload' => $upload->reveal()]); + + $this->assertTrue($validator->isValid('test')); } /** @@ -290,34 +273,42 @@ public function testGetFiles() $this->assertEquals([], $validator->getFiles('test5')); } - public function testPsrGetFiles() + public function testGetFilesReturnsArtifactsFromPsr7UploadedFiles() { + $upload1 = $this->prophesize(UploadedFileInterface::class); + $upload1->getClientFilename()->willReturn('test1'); + + $upload2 = $this->prophesize(UploadedFileInterface::class); + $upload2->getClientFilename()->willReturn('test3'); + $files = [ - 'test' => new UploadedFile( - 'tmp_test1', - 200, - 0, - 'test1', - 'text' - ), - 'test2' => new UploadedFile( - 'tmp_test2', - 202, - 1, - 'test3', - 'text2' - ) + 'test' => $upload1->reveal(), + 'test2' => $upload2->reveal(), ]; $validator = new File\Upload(); $validator->setFiles($files); + + // Retrieve by index $this->assertEquals(['test' => $files['test']], $validator->getFiles('test')); + $this->assertEquals(['test2' => $files['test2']], $validator->getFiles('test2')); + + // Retrieve by client filename $this->assertEquals(['test' => $files['test']], $validator->getFiles('test1')); $this->assertEquals(['test2' => $files['test2']], $validator->getFiles('test3')); + return $validator; + } + + /** + * @depends testGetFilesReturnsArtifactsFromPsr7UploadedFiles + */ + public function testGetFilesRaisesExceptionWhenPsr7UploadedFilesArrayDoesNotContainGivenFilename( + File\Upload $validator + ) { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('was not found'); - $this->assertEquals([], $validator->getFiles('test5')); + $validator->getFiles('test5'); } /** @@ -359,28 +350,19 @@ public function testSetFiles() $this->assertEquals($files, $validator->getFiles()); } - public function testPsrSetFiles() + public function testCanPopulateFilesFromArrayOfPsr7UploadedFiles() { + $upload1 = $this->prophesize(UploadedFileInterface::class); + $upload2 = $this->prophesize(UploadedFileInterface::class); + $psrFiles = [ - 'test4' => new UploadedFile( - 'tmp_test4', - 204, - 3, - 'test4', - 'text5' - ), - 'test5' => new UploadedFile( - 'tmp_test5', - 205, - 4, - 'test5', - 'text5' - ) + 'test4' => $upload1->reveal(), + 'test5' => $upload2->reveal(), ]; $validator = new File\Upload(); $validator->setFiles($psrFiles); - $this->assertEquals($psrFiles, $validator->getFiles()); + $this->assertSame($psrFiles, $validator->getFiles()); } /** @@ -440,32 +422,4 @@ public function testErrorMessage() $validator->getMessages() ); } - - /** - * @group ZF-12128 - */ - public function testPsrErrorMessage() - { - $files = [ - 'foo' => new UploadedFile( - 'tmp_bar', - 100, - 7, - 'bar', - 'text' - ) - ]; - - $validator = new File\Upload; - $validator->setFiles($files); - $validator->isValid('foo'); - - $this->assertEquals( - [ - 'fileUploadErrorCantWrite' => "Failed to write file 'bar' to disk", - ], - $validator->getMessages() - ); - $validator->setFiles($files); - } } From e8dcc31e123df889beeb1b58b4f7599511b2a53b Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 13 Dec 2018 15:04:25 -0600 Subject: [PATCH 15/18] Updates Upload and UploadFile docs to note PSR-7 support --- doc/book/validators/file/upload-file.md | 22 +++++++++++++++++++-- doc/book/validators/file/upload.md | 26 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/doc/book/validators/file/upload-file.md b/doc/book/validators/file/upload-file.md index 80a8b8372..b389d2673 100644 --- a/doc/book/validators/file/upload-file.md +++ b/doc/book/validators/file/upload-file.md @@ -3,7 +3,7 @@ `Zend\Validator\File\UploadFile` checks whether a single file has been uploaded via a form `POST` and will return descriptive messages for any upload errors. -# Basic Usage +## Basic Usage ```php use Zend\Http\PhpEnvironment\Request; @@ -19,7 +19,25 @@ if ($validator->isValid($files['my-upload'])) { } ``` +## PSR-7 Support + +- Since 2.11.0 + +Starting in 2.11.0, you can also pass [PSR-7 UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#uploadedfileinterface) +instances as values to the validator. When valid, `getValue()` will return the +instance validated verbatim: + +```php +$validator = new UploadFile(); + +// @var Psr\Http\Message\UploadedFileInterface $uploadedFile +if ($validator->isValid($uploadedFile)) { + // file is valid + $validInstance = $validator->getValue(); // === $uploadedFile +} +``` + ## Usage with zend-inputfilter -When using zend-inputfilter's [FileInput](https://zendframework.github.io/zend-inputfilter/file-input/), +When using zend-inputfilter's [FileInput](https://docs.zendframework.com/zend-inputfilter/file-input/), this validator will be automatically prepended to the validator chain. diff --git a/doc/book/validators/file/upload.md b/doc/book/validators/file/upload.md index a27661b0a..d7823179e 100644 --- a/doc/book/validators/file/upload.md +++ b/doc/book/validators/file/upload.md @@ -28,3 +28,29 @@ if ($validator->isValid('foo')) { // "foo" file upload was successful } ``` + +## PSR-7 Support + +- Since 2.11.0 + +Starting in 2.11.0, you can also pass an array of [PSR-7 UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#uploadedfileinterface) +instances to the constructor, the `setFiles()` method, or the `isValid()` +method (in the latter case, you are validating that _all_ uploaded files were +valid). + +```php +use Zend\Validator\File\Upload; + +// @var Psr\Http\Message\ServerRequestInterface $request +$validator = new Upload($request->getUploadedFiles()); + +// Or using options notation: +$validator = new Upload([ + 'files' => $request->getUploadedFiles(), +]); + +// Validate: +if ($validator->isValid('foo')) { + // "foo" file upload was successful +} +``` From a10270abb587d749b8152a2e68f2419dbbac48ff Mon Sep 17 00:00:00 2001 From: Sasha Alex Romanenko Date: Thu, 16 Aug 2018 18:06:48 -0400 Subject: [PATCH 16/18] Changelog. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17506def2..0c142730d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ All notable changes to this project will be documented in this file, in reverse ### Added +- [#237](https://github.com/zendframework/zend-validator/pull/237) adds support for the [PSR-7 UploadedFileInterface](https://www.php-fig.org/psr/psr-7/#uploadedfileinterface) + to each of the `Upload` and `UploadFile` validators. + - [#220](https://github.com/zendframework/zend-validator/pull/220) adds image/webp to the list of known image types for the `IsImage` validator. ### Changed From 1ab5f1603683f87af6d4528eb86dffd0457fa81b Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 13 Dec 2018 15:22:36 -0600 Subject: [PATCH 17/18] Bumps branch aliases - dev-master => 2.11.x-dev - dev-develop => 2.12.x-dev --- composer.json | 4 ++-- composer.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index bffa84135..fc087554c 100644 --- a/composer.json +++ b/composer.json @@ -47,8 +47,8 @@ "prefer-stable": true, "extra": { "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "2.11.x-dev" + "dev-master": "2.11.x-dev", + "dev-develop": "2.12.x-dev" }, "zf": { "component": "Zend\\Validator", diff --git a/composer.lock b/composer.lock index 59a733a6e..fd89f9643 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ad99d8812f502736c10c2285a57b1cbf", + "content-hash": "6d7da53324a7d53b31d05453a72e1136", "packages": [ { "name": "container-interop/container-interop", From 5f05b02958fcb1203540b66473138526431982d3 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 13 Dec 2018 15:23:03 -0600 Subject: [PATCH 18/18] 2.11.0 readiness --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c142730d..44b660e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 2.11.0 - TBD +## 2.11.0 - 2018-12-13 ### Added