<?php
/**
* @see https://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
*/
namespace Zend\Diactoros;
use InvalidArgumentException;
use Psr\Http\Message\UploadedFileInterface;
use function is_array;
/**
* Normalize uploaded files
*
* Transforms each value into an UploadedFile instance, and ensures that nested
* arrays are normalized.
*
* @param array $files
* @return UploadedFileInterface[]
* @throws InvalidArgumentException for unrecognized values
*/
function normalizeUploadedFiles(array $files)
{
/**
* Traverse a nested tree of uploaded file specifications.
*
* @param string[]|array[] $tmpNameTree
* @param int[]|array[] $sizeTree
* @param int[]|array[] $errorTree
* @param string[]|array[]|null $nameTree
* @param string[]|array[]|null $typeTree
* @return UploadedFile[]|array[]
*/
$recursiveNormalize = function (
array $tmpNameTree,
array $sizeTree,
array $errorTree,
array $nameTree = null,
array $typeTree = null
) use (&$recursiveNormalize) {
$normalized = [];
foreach ($tmpNameTree as $key => $value) {
if (is_array($value)) {
// Traverse
$normalized[$key] = $recursiveNormalize(
$tmpNameTree[$key],
$sizeTree[$key],
$errorTree[$key],
isset($nameTree[$key]) ? $nameTree[$key] : null,
isset($typeTree[$key]) ? $typeTree[$key] : null
);
continue;
}
$normalized[$key] = createUploadedFile([
'tmp_name' => $tmpNameTree[$key],
'size' => $sizeTree[$key],
'error' => $errorTree[$key],
'name' => isset($nameTree[$key]) ? $nameTree[$key] : null,
'type' => isset($typeTree[$key]) ? $typeTree[$key] : null
]);
}
return $normalized;
};
/**
* Normalize an array of file specifications.
*
* Loops through all nested files (as determined by receiving an array to the
* `tmp_name` key of a `$_FILES` specification) and returns a normalized array
* of UploadedFile instances.
*
* This function normalizes a `$_FILES` array representing a nested set of
* uploaded files as produced by the php-fpm SAPI, CGI SAPI, or mod_php
* SAPI.
*
* @param array $files
* @return UploadedFile[]
*/
$normalizeUploadedFileSpecification = function (array $files = []) use (&$recursiveNormalize) {
if (! isset($files['tmp_name']) || ! is_array($files['tmp_name'])
|| ! isset($files['size']) || ! is_array($files['size'])
|| ! isset($files['error']) || ! is_array($files['error'])
) {
throw new InvalidArgumentException(sprintf(
'$files provided to %s MUST contain each of the keys "tmp_name",'
. ' "size", and "error", with each represented as an array;'
. ' one or more were missing or non-array values',
__FUNCTION__
));
}
return $recursiveNormalize(
$files['tmp_name'],
$files['size'],
$files['error'],
isset($files['name']) ? $files['name'] : null,
isset($files['type']) ? $files['type'] : null
);
};
$normalized = [];
foreach ($files as $key => $value) {
if ($value instanceof UploadedFileInterface) {
$normalized[$key] = $value;
continue;
}
if (is_array($value) && isset($value['tmp_name']) && is_array($value['tmp_name'])) {
$normalized[$key] = $normalizeUploadedFileSpecification($value);
continue;
}
if (is_array($value) && isset($value['tmp_name'])) {
$normalized[$key] = createUploadedFile($value);
continue;
}
if (is_array($value)) {
$normalized[$key] = normalizeUploadedFiles($value);
continue;
}
throw new InvalidArgumentException('Invalid value in files specification');
}
return $normalized;
}