Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
UpdateResultsEndpoint
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
1 / 1
7
100.00% covered (success)
100.00%
1 / 1
 handle
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
1 / 1
7
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            $new_content = base64_decode($input['content']);
40            if (!$new_content) {
41                $this->log()->warning("Invalid base64 data");
42                return ['status' => 'INVALID_BASE64_DATA'];
43            }
44            file_put_contents($file_path, $new_content);
45        } elseif ($input['iofXmlFileId'] ?? false) {
46            $upload_id = $input['iofXmlFileId'];
47            $upload_path = "{$data_path}temp/{$upload_id}";
48            if (!is_file($upload_path)) {
49                throw new HttpError(400, 'Uploaded file not found!');
50            }
51            rename($upload_path, $file_path);
52        } else {
53            throw new HttpError(400, 'Either iofXmlFileId or content must be set!');
54        }
55
56        $iso_now = $this->dateUtils()->getCurrentDateInFormat('Y-m-d H:i:s');
57        file_put_contents(
58            "{$results_data_path}/_live.json",
59            json_encode([
60                'file' => $filename,
61                'last_updated_at' => $iso_now,
62            ]),
63        );
64        return ['status' => 'OK'];
65    }
66}