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

View File

@ -369,7 +369,7 @@ class ServerRequestTest extends \PHPUnit_Framework_TestCase
public function testWithUploadedFilesCreatesNewInstance()
{
$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();
$request1 = $request->withUploadedFiles([]);
@ -380,17 +380,32 @@ class ServerRequestTest extends \PHPUnit_Framework_TestCase
/**
* @covers WellRESTed\Message\ServerRequest::withUploadedFiles
* @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 = $request->withUploadedFiles($uploadedFiles);
$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::isValidUploadedFilesTree
@ -408,33 +423,54 @@ class ServerRequestTest extends \PHPUnit_Framework_TestCase
return [
// All keys must be strings
[[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.
[
[
"file" =>
[
"file1" => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)
]
]
[new UploadedFile("index1.html", "text/html", 524, "/tmp/php9hNlHe", 0)],
[new UploadedFile("index2.html", "text/html", 524, "/tmp/php9hNlHe", 0)]
],
[
[
"file" => [
0 => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0),
2 => new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0)
"single" => [
"name" => "single.txt",
"type" => "text/plain",
"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
]
]
],
[
[
"file" => [
new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0),
new UploadedFile("index.html", "text/html", 524, "/tmp/php9hNlHe", 0),
"index.html"
],
"nestedList" => [
"level2" => [
"name" => [
0 => "nestedList0.jpg",
1 => "nestedList1.jpg",
2 => ""
],
"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
]
]
]
]