Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ManagementCrashReportDetailLogic
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 3
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validateImpl
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 executeImpl
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\App\Models\Domain\Page\Management;
6
7use Exception;
8use PeServer\App\Models\AppCryptography;
9use PeServer\App\Models\AppDatabaseCache;
10use PeServer\App\Models\AppUrl;
11use PeServer\App\Models\Dao\Domain\CrashReportDomainDao;
12use PeServer\App\Models\Dao\Entities\CrashReportCommentsEntityDao;
13use PeServer\App\Models\Dao\Entities\CrashReportsEntityDao;
14use PeServer\App\Models\Domain\AppArchiver;
15use PeServer\App\Models\Domain\Page\PageLogicBase;
16use PeServer\Core\Archiver;
17use PeServer\Core\Binary;
18use PeServer\Core\Collection\Arr;
19use PeServer\Core\Database\IDatabaseContext;
20use PeServer\Core\Http\HttpStatus;
21use PeServer\Core\Mvc\LogicCallMode;
22use PeServer\Core\Mvc\LogicParameter;
23use PeServer\Core\Text;
24use PeServer\Core\Throws\HttpStatusException;
25use PeServer\Core\Stopwatch;
26use PeServer\Core\Store\SpecialStore;
27
28class ManagementCrashReportDetailLogic extends PageLogicBase
29{
30    public function __construct(LogicParameter $parameter, private SpecialStore $specialStore, private AppCryptography $appCryptography)
31    {
32        parent::__construct($parameter);
33    }
34
35    protected function validateImpl(LogicCallMode $callMode): void
36    {
37        $this->validation('sequence', function ($key, $value) {
38            $hasSequence = $this->validator->isNotEmpty($key, $value);
39
40            if ($hasSequence) {
41                $database = $this->openDatabase();
42                $crashReportsEntityDao = new CrashReportsEntityDao($database);
43
44                $seq = (int)$value;
45                $exists = $crashReportsEntityDao->selectExistsCrashReportsBySequence($seq);
46                if (!$exists) {
47                    throw new HttpStatusException(HttpStatus::NotFound);
48                }
49            } else {
50                throw new HttpStatusException(HttpStatus::BadRequest);
51            }
52        });
53    }
54
55    protected function executeImpl(LogicCallMode $callMode): void
56    {
57        $sequence = (int)$this->getRequest('sequence');
58        $this->result['sequence'] = $sequence;
59
60        $database = $this->openDatabase();
61        $crashReportDomainDao = new CrashReportDomainDao($database);
62
63        $detail = $crashReportDomainDao->selectCrashReportsDetail($sequence);
64
65        $this->setValue('detail', $detail);
66        if (Text::isNullOrWhiteSpace($detail->email)) {
67            $this->setValue('email', Text::EMPTY);
68        } else {
69            $email = $this->appCryptography->decrypt($detail->email);
70            $this->setValue('email', $email);
71        }
72
73        $compressReport = new Binary($detail->report);
74        if ($compressReport->count()) {
75            $report = Archiver::extractGzip($compressReport)->toBase64();
76            $this->setValue('report', $report);
77        } else {
78            $this->setValue('report', Text::EMPTY);
79        }
80
81        $this->setValue('developer_title', "[CR:$sequence] (edit title)");
82
83        $exception = $detail->exception;
84
85        $body = Text::replaceMap(
86            <<<STR
87{URL}
88
89{VERSION}
90
91```
92{EXCEPTION}
93```
94
95---
96
97(edit body)
98
99STR,
100            [
101                'URL' => $this->specialStore->getRequestUrl()->toString(),
102                'VERSION' => $detail->version,
103                'EXCEPTION' => $exception
104            ]
105        );
106        $this->setValue('developer_body', $body);
107
108        if ($callMode === LogicCallMode::Initialize) {
109            $this->setValue('developer-comment', $detail->developerComment);
110            return;
111        }
112
113        $developerComment = (string)$this->getRequest('developer-comment');
114
115        $result = $database->transaction(function (IDatabaseContext $context) use ($sequence, $developerComment) {
116            $crashReportCommentsEntityDao = new CrashReportCommentsEntityDao($context);
117
118            if ($crashReportCommentsEntityDao->selectExistsCrashReportCommentsBySequence($sequence)) {
119                $crashReportCommentsEntityDao->updateCrashReportComments($sequence, $developerComment);
120            } else {
121                $crashReportCommentsEntityDao->insertCrashReportComments($sequence, $developerComment);
122            }
123
124            return true;
125        });
126        if (!$result) {
127            throw new HttpStatusException(HttpStatus::InternalServerError);
128        }
129    }
130}