Update uploaded file functionality in ServerRequest

This commit is contained in:
PJ Dietz 2015-04-30 22:10:40 -04:00
parent b76883c9e9
commit 257f2b7610
2 changed files with 94 additions and 48 deletions

View File

@ -4,6 +4,7 @@ namespace WellRESTed\Message;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
/** /**
* Representation of an incoming, server-side HTTP request. * Representation of an incoming, server-side HTTP request.
@ -193,7 +194,7 @@ class ServerRequest extends Request implements ServerRequestInterface
{ {
if (!$this->isValidUploadedFilesTree($uploadedFiles)) { if (!$this->isValidUploadedFilesTree($uploadedFiles)) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
"withUploadedFiles expects an array with string keys and UploadedFileInterface[] values"); "withUploadedFiles expects an array tree with UploadedFileInterface leaves.");
} }
$request = clone $this; $request = clone $this;
@ -475,36 +476,45 @@ class ServerRequest extends Request implements ServerRequestInterface
return $headers; return $headers;
} }
/**
* @param array $uploadedFiles
* @return bool
*/
private function isValidUploadedFilesTree(array $uploadedFiles) private function isValidUploadedFilesTree(array $uploadedFiles)
{ {
// Ensure all keys are strings. // Allow empty array.
if (count($uploadedFiles) === 0) {
return true;
}
// All keys MUST be strings.
$keys = array_keys($uploadedFiles); $keys = array_keys($uploadedFiles);
if (count($keys) !== count(array_filter($keys, "is_string"))) { if (count($keys) !== count(array_filter($keys, "is_string"))) {
return false; return false;
} }
// All values must be UploadedFileInterface[]. foreach ($uploadedFiles as $branch) {
if (!$this->isValidUploadedFilesBranch($branch)) {
return false;
}
}
// Ensure all values are arrays. return true;
$values = array_values($uploadedFiles); }
if (count($values) !== count(array_filter($values, "is_array"))) {
private function isValidUploadedFilesBranch($branch)
{
if ($branch instanceof UploadedFileInterface) {
return true;
}
if (!is_array($branch)) {
return false; return false;
} }
$isUploadedFileInterface = function ($object) { $values = array_values($branch);
return is_object($object) && in_array('Psr\Http\Message\UploadedFileInterface', class_implements($object)); foreach ($values as $value) {
}; if (!$this->isValidUploadedFilesBranch($value)) {
foreach ($values as $items) {
// Ensure values are list arrays.
if (array_keys($items) !== range(0, count($items) - 1)) {
return false;
}
// Ensure all items are UploadedFileInterfaces
$itemValues = array_values($items);
if (count($itemValues) !== count(array_filter($itemValues, $isUploadedFileInterface))) {
return false; return false;
} }
} }

View File

@ -369,7 +369,7 @@ class ServerRequestTest extends \PHPUnit_Framework_TestCase
public function testWithUploadedFilesCreatesNewInstance() public function testWithUploadedFilesCreatesNewInstance()
{ {
$uploadedFiles = [ $uploadedFiles = [
"file" => [new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)] "file" => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)
]; ];
$request = new ServerRequest(); $request = new ServerRequest();
$request1 = $request->withUploadedFiles([]); $request1 = $request->withUploadedFiles([]);
@ -380,17 +380,32 @@ class ServerRequestTest extends \PHPUnit_Framework_TestCase
/** /**
* @covers WellRESTed\Message\ServerRequest::withUploadedFiles * @covers WellRESTed\Message\ServerRequest::withUploadedFiles
* @covers WellRESTed\Message\ServerRequest::isValidUploadedFilesTree * @covers WellRESTed\Message\ServerRequest::isValidUploadedFilesTree
* @dataProvider validUploadedFilesProvider
*/ */
public function testWithUploadedFilesReturnsPassedUploadedFiles() public function testWithUploadedFilesReturnsPassedUploadedFiles($uploadedFiles)
{ {
$uploadedFiles = [
"file" => [new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)]
];
$request = new ServerRequest(); $request = new ServerRequest();
$request = $request->withUploadedFiles($uploadedFiles); $request = $request->withUploadedFiles($uploadedFiles);
$this->assertSame($uploadedFiles, $request->getUploadedFiles()); $this->assertSame($uploadedFiles, $request->getUploadedFiles());
} }
public function validUploadedFilesProvider()
{
return [
[[]],
[["files" => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)]],
[["nested" => [
"level2" => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)
]]],
[["nestedList" => [
"level2" => [
new UploadedFile("file1.html", "text/html", 524, "/tmp/php9hNlHe", 0),
new UploadedFile("file2.html", "text/html", 524, "/tmp/php9hNshj", 0)
]
]]]
];
}
/** /**
* @covers WellRESTed\Message\ServerRequest::withUploadedFiles * @covers WellRESTed\Message\ServerRequest::withUploadedFiles
* @covers WellRESTed\Message\ServerRequest::isValidUploadedFilesTree * @covers WellRESTed\Message\ServerRequest::isValidUploadedFilesTree
@ -408,33 +423,54 @@ class ServerRequestTest extends \PHPUnit_Framework_TestCase
return [ return [
// All keys must be strings // All keys must be strings
[[new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)]], [[new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)]],
// All values must be arrays.
[["file" => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)]],
// All values must be list arrays.
[ [
[ [new UploadedFile("index1.html", "text/html", 524, "/tmp/php9hNlHe", 0)],
"file" => [new UploadedFile("index2.html", "text/html", 524, "/tmp/php9hNlHe", 0)]
[
"file1" => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)
]
]
], ],
[ [
[ "single" => [
"file" => [ "name" => "single.txt",
0 => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0), "type" => "text/plain",
2 => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0) "tmp_name" => "/tmp/php9hNlHe",
"error" => UPLOAD_ERR_OK,
"size" => 524
],
"nested" => [
"level2" => [
"name" => "nested.json",
"type" => "application/json",
"tmp_name" => "/tmp/phpadhjk",
"error" => UPLOAD_ERR_OK,
"size" => 1024
] ]
] ],
], "nestedList" => [
[ "level2" => [
[ "name" => [
"file" => [ 0 => "nestedList0.jpg",
new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0), 1 => "nestedList1.jpg",
new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0), 2 => ""
"index.html" ],
"type" => [
0 => "image/jpeg",
1 => "image/jpeg",
2 => ""
],
"tmp_name" => [
0 => "/tmp/phpjpg0",
1 => "/tmp/phpjpg1",
2 => ""
],
"error" => [
0 => UPLOAD_ERR_OK,
1 => UPLOAD_ERR_OK,
2 => UPLOAD_ERR_NO_FILE
],
"size" => [
0 => 256,
1 => 4096,
2 => 0
]
] ]
] ]
] ]