1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Bridge\PsrHttpMessage\Factory;
13
14use Psr\Http\Message\UploadedFileInterface;
15use Symfony\Component\HttpFoundation\File\Exception\FileException;
16use Symfony\Component\HttpFoundation\File\File;
17use Symfony\Component\HttpFoundation\File\UploadedFile as BaseUploadedFile;
18
19/**
20 * @author Nicolas Grekas <p@tchwork.com>
21 */
22class UploadedFile extends BaseUploadedFile
23{
24    private $psrUploadedFile;
25    private $test = false;
26
27    public function __construct(UploadedFileInterface $psrUploadedFile, callable $getTemporaryPath)
28    {
29        $error = $psrUploadedFile->getError();
30        $path = '';
31
32        if (\UPLOAD_ERR_NO_FILE !== $error) {
33            $path = $psrUploadedFile->getStream()->getMetadata('uri') ?? '';
34
35            if ($this->test = !\is_string($path) || !is_uploaded_file($path)) {
36                $path = $getTemporaryPath();
37                $psrUploadedFile->moveTo($path);
38            }
39        }
40
41        parent::__construct(
42            $path,
43            (string) $psrUploadedFile->getClientFilename(),
44            $psrUploadedFile->getClientMediaType(),
45            $psrUploadedFile->getError(),
46            $this->test
47        );
48
49        $this->psrUploadedFile = $psrUploadedFile;
50    }
51
52    /**
53     * {@inheritdoc}
54     */
55    public function move($directory, $name = null): File
56    {
57        if (!$this->isValid() || $this->test) {
58            return parent::move($directory, $name);
59        }
60
61        $target = $this->getTargetFile($directory, $name);
62
63        try {
64            $this->psrUploadedFile->moveTo($target);
65        } catch (\RuntimeException $e) {
66            throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, $e->getMessage()), 0, $e);
67        }
68
69        @chmod($target, 0666 & ~umask());
70
71        return $target;
72    }
73}
74