Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
UpdateResultsEndpoint
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
72
0.00% covered (danger)
0.00%
0 / 1
 handle
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3namespace Olz\Apps\Results\Endpoints;
4
5use Olz\Api\OlzTypedEndpoint;
6use PhpTypeScriptApi\HttpError;
7
8/**
9 * @extends OlzTypedEndpoint<
10 *   array{
11 *     file: non-empty-string,
12 *     content?: ?non-empty-string,
13 *     iofXmlFileId?: ?non-empty-string,
14 *   },
15 *   array{status: 'OK'|'INVALID_FILENAME'|'INVALID_BASE64_DATA'|'ERROR'}
16 * >
17 */
18class UpdateResultsEndpoint extends OlzTypedEndpoint {
19    protected function handle(mixed $input): mixed {
20        $this->checkPermission('any');
21
22        $data_path = $this->envUtils()->getDataPath();
23        $filename = $input['file'];
24        $is_filename_ok = preg_match('/^[a-z0-9\-\.]+$/', $filename);
25        if (!$is_filename_ok) {
26            $this->log()->warning("Filename must match ^[a-z0-9\\-\\.]+$: {$filename}");
27            return ['status' => 'INVALID_FILENAME'];
28        }
29        $results_data_path = realpath("{$data_path}results");
30        $file_path = "{$results_data_path}/{$filename}";
31        if (is_file($file_path)) {
32            $iso_t_now = $this->dateUtils()->getCurrentDateInFormat("Y-m-d_H:i:s");
33            rename(
34                $file_path,
35                $file_path.".bak_".$iso_t_now,
36            );
37        }
38        if ($input['content'] ?? false) {
39            $res = preg_match("/^data\\:([^\\;]*)\\;base64\\,(.+)$/", $input['content'], $matches);
40            $base64 = $res ? $matches[2] : $input['content'];
41            $new_content = base64_decode($base64);
42            if (!$new_content) {
43                $this->log()->warning("Invalid base64 data");
44                return ['status' => 'INVALID_BASE64_DATA'];
45            }
46            file_put_contents($file_path, $new_content);
47        } elseif ($input['iofXmlFileId'] ?? false) {
48            $upload_id = $input['iofXmlFileId'];
49            $upload_path = "{$data_path}temp/{$upload_id}";
50            if (!is_file($upload_path)) {
51                throw new HttpError(400, 'Uploaded file not found!');
52            }
53            rename($upload_path, $file_path);
54        } else {
55            throw new HttpError(400, 'Either iofXmlFileId or content must be set!');
56        }
57
58        $iso_now = $this->dateUtils()->getCurrentDateInFormat('Y-m-d H:i:s');
59        file_put_contents(
60            "{$results_data_path}/_live.json",
61            json_encode([
62                'file' => $filename,
63                'last_updated_at' => $iso_now,
64            ]),
65        );
66        return ['status' => 'OK'];
67    }
68}