aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/app/src/Models/Answer.php
blob: 6cb800628c35a67963302d9a7d92a72c55728c9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php

declare(strict_types=1);

namespace Nsfisis\Albatross\Models;

use DateTimeImmutable;
use Nsfisis\Albatross\Exceptions\EntityValidationException;

final class Answer
{
    public function __construct(
        public readonly int $answer_id,
        public readonly int $quiz_id,
        public readonly int $answer_number,
        public readonly DateTimeImmutable $submitted_at,
        public readonly int $author_id,
        public readonly string $code,
        public readonly int $code_size,
        public readonly AggregatedExecutionStatus $execution_status,
        public readonly ?string $author_name, // joined
        public readonly ?bool $author_is_admin, // joined
    ) {
    }

    public static function create(
        int $quiz_id,
        int $author_id,
        string $code,
    ): self {
        self::validate($quiz_id, $author_id, $code);
        $answer = new self(
            answer_id: 0,
            quiz_id: $quiz_id,
            answer_number: 0,
            submitted_at: new DateTimeImmutable(), // dummy
            author_id: $author_id,
            code: $code,
            code_size: strlen(self::normalizeCode($code)), // not mb_strlen
            execution_status: AggregatedExecutionStatus::Pending,
            author_name: null,
            author_is_admin: null,
        );
        return $answer;
    }

    private static function validate(
        int $quiz_id,
        int $author_id,
        string $code,
    ): void {
        $errors = [];
        if (strlen($code) <= 0) {
            $errors['code'] = 'コードを入力してください';
        }
        if (10 * 1024 <= strlen($code)) {
            $errors['code'] = 'コードが長すぎます。10 KiB 未満まで縮めてください';
        }

        if (0 < count($errors)) {
            throw new EntityValidationException(errors: $errors);
        }
    }

    public static function normalizeCode(string $code): string
    {
        return preg_replace('/^\s*<\?(?:php\b)?\s*/', '', str_replace(["\r\n", "\r"], "\n", $code)) ?? $code;
    }
}