| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 | <?php/* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */namespace Symfony\Component\HttpFoundation;use Symfony\Component\HttpFoundation\File\UploadedFile;/** * FileBag is a container for uploaded files. * * @author Fabien Potencier <fabien@symfony.com> * @author Bulat Shakirzyanov <mallluhuct@gmail.com> */class FileBag extends ParameterBag{    private const FILE_KEYS = ['error', 'name', 'size', 'tmp_name', 'type'];    /**     * @param array|UploadedFile[] $parameters An array of HTTP files     */    public function __construct(array $parameters = [])    {        $this->replace($parameters);    }    /**     * {@inheritdoc}     */    public function replace(array $files = [])    {        $this->parameters = [];        $this->add($files);    }    /**     * {@inheritdoc}     */    public function set(string $key, $value)    {        if (!\is_array($value) && !$value instanceof UploadedFile) {            throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');        }        parent::set($key, $this->convertFileInformation($value));    }    /**     * {@inheritdoc}     */    public function add(array $files = [])    {        foreach ($files as $key => $file) {            $this->set($key, $file);        }    }    /**     * Converts uploaded files to UploadedFile instances.     *     * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information     *     * @return UploadedFile[]|UploadedFile|null     */    protected function convertFileInformation($file)    {        if ($file instanceof UploadedFile) {            return $file;        }        $file = $this->fixPhpFilesArray($file);        $keys = array_keys($file);        sort($keys);        if (self::FILE_KEYS == $keys) {            if (\UPLOAD_ERR_NO_FILE == $file['error']) {                $file = null;            } else {                $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false);            }        } else {            $file = array_map(function ($v) { return $v instanceof UploadedFile || \is_array($v) ? $this->convertFileInformation($v) : $v; }, $file);            if (array_keys($keys) === $keys) {                $file = array_filter($file);            }        }        return $file;    }    /**     * Fixes a malformed PHP $_FILES array.     *     * PHP has a bug that the format of the $_FILES array differs, depending on     * whether the uploaded file fields had normal field names or array-like     * field names ("normal" vs. "parent[child]").     *     * This method fixes the array to look like the "normal" $_FILES array.     *     * It's safe to pass an already converted array, in which case this method     * just returns the original array unmodified.     *     * @return array     */    protected function fixPhpFilesArray(array $data)    {        // Remove extra key added by PHP 8.1.        unset($data['full_path']);        $keys = array_keys($data);        sort($keys);        if (self::FILE_KEYS != $keys || !isset($data['name']) || !\is_array($data['name'])) {            return $data;        }        $files = $data;        foreach (self::FILE_KEYS as $k) {            unset($files[$k]);        }        foreach ($data['name'] as $key => $name) {            $files[$key] = $this->fixPhpFilesArray([                'error' => $data['error'][$key],                'name' => $name,                'type' => $data['type'][$key],                'tmp_name' => $data['tmp_name'][$key],                'size' => $data['size'][$key],            ]);        }        return $files;    }}
 |