1fd23b200f84fb8d0662e765f11966a77afaee5a
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / action / FileUploadPreflightAction.class.php
1 <?php
2
3 namespace wcf\action;
4
5 use Laminas\Diactoros\Response\JsonResponse;
6 use Psr\Http\Message\ResponseInterface;
7 use Psr\Http\Message\ServerRequestInterface;
8 use Psr\Http\Server\RequestHandlerInterface;
9 use wcf\http\Helper;
10 use wcf\system\request\LinkHandler;
11 use wcf\system\WCF;
12
13 final class FileUploadPreflightAction implements RequestHandlerInterface
14 {
15 public function handle(ServerRequestInterface $request): ResponseInterface
16 {
17 // TODO: For now we only require the filename and size to be provided.
18 $parameters = Helper::mapQueryParameters(
19 $request->getParsedBody(),
20 <<<'EOT'
21 array {
22 filename: non-empty-string,
23 filesize: positive-int,
24 }
25 EOT,
26 );
27
28 // TODO: The chunk calculation shouldn’t be based on a fixed number.
29 $chunkSize = 2_000_000;
30 $chunks = (int)\ceil($parameters['filesize'] / $chunkSize);
31
32 $identifier = $this->createTemporaryFile($parameters);
33
34 $endpoints = [];
35 for ($i = 0; $i < $chunks; $i++) {
36 $endpoints[] = LinkHandler::getInstance()->getControllerLink(
37 FileUploadAction::class,
38 [
39 'identifier' => $identifier,
40 'sequenceNo' => $i,
41 ]
42 );
43 }
44
45 return new JsonResponse([
46 'endpoints' => $endpoints,
47 ]);
48 }
49
50 private function createTemporaryFile(array $parameters): string
51 {
52 $identifier = \bin2hex(\random_bytes(20));
53
54 $sql = "INSERT INTO wcf1_file_temporary
55 (identifier, time, filename, filesize)
56 VALUES (?, ?, ?, ?)";
57 $statement = WCF::getDB()->prepare($sql);
58 $statement->execute([
59 $identifier,
60 \TIME_NOW,
61 $parameters['filename'],
62 $parameters['filesize'],
63 ]);
64
65 return $identifier;
66 }
67 }