7 private const TOKEN_SCOPE =
'dbxSelfTest.actions';
13 $this->runner =
dbx()->get_include_obj(
'dbxSelfTestRunner',
'dbxSelfTest');
18 private function h(
$value):
string
20 return htmlspecialchars((
string)
$value, ENT_QUOTES,
'UTF-8');
23 private function url(
string $action,
bool $tokenized =
false, array $params = array()):
string
25 $url =
'?dbx_modul=dbxSelfTest&dbx_run1=' . rawurlencode($action);
26 foreach ($params as $key =>
$value) {
27 $url .=
'&' . rawurlencode((
string)$key) .
'=' . rawurlencode((
string)
$value);
35 private function payload(): array
37 $raw = file_get_contents(
'php://input');
38 $data = is_string($raw) && trim($raw) !==
'' ? json_decode($raw,
true) : array();
39 return is_array($data) ? $data : array();
42 private function requireToken(
string $action):
void
44 $token = (string)
dbx()->get_modul_var(
'dbx_token',
'',
'varchar|max=128');
48 dbx()->sys_msg(
'security',
'dbxSelfTest Token abgewiesen: ' . $action);
49 http_response_code(403);
50 dbx()->json_response(array(
'ok' => 0,
'error' =>
'Sicherheitstoken ungueltig. Bitte Seite neu laden.'),
true);
53 private function json(array $data):
void
55 dbx()->json_response($data,
true);
58 private function publicCatalog(): array
60 return array_map(
static function (array $test): array {
61 unset($test[
'handler']);
63 }, $this->runner()->catalog(
'full'));
66 private function dashboard():
string
68 $catalog = $this->runner()->catalog(
'full');
69 $quick = $this->runner()->catalog(
'quick');
70 $categories = array_unique(array_column(
$catalog,
'category'));
72 dbx()->set_system_var(
'dbx_title',
'System-Selbsttest');
74 return dbx()->get_system_obj(
'dbxTPL')->get_tpl(
'dbxSelfTest|selftest-dashboard', array(
76 'quick_count' => count($quick),
77 'category_count' => count($categories),
78 'catalog_url' => $this->h($this->url(
'api_catalog')),
79 'start_url' => $this->h($this->url(
'api_start',
true)),
80 'execute_url' => $this->h($this->url(
'api_execute',
true)),
81 'finish_url' => $this->h($this->url(
'api_finish',
true)),
82 'browser_result_url' => $this->h($this->url(
'api_browser_result',
true)),
83 'run_url' => $this->h($this->url(
'api_run')),
84 'download_url' => $this->h($this->url(
'download')),
85 'bar_title' =>
'dbxSelfTest',
86 'bar_subtitle' =>
'Komplett-, Schnell- und Einzeltests mit dauerhaftem Protokoll.',
87 'bar_icon' =>
'bi-clipboard2-pulse',
88 'bar_actions' =>
'<a class="btn btn-outline-secondary btn-sm" href="' . $this->h($this->url(
'dashboard')) .
'"><i class="bi bi-arrow-clockwise"></i> Aktualisieren</a>',
89 'bar_class' =>
'dbx-module-bar',
90 'bar_title_class' =>
'dbx-module-bar-titleblock',
91 'bar_title_pre' =>
'',
92 'bar_title_heading_attrs' =>
'',
95 'bar_actions_class' =>
'dbx-module-bar-actions',
99 private function apiCatalog():
void
103 'tests' => $this->publicCatalog(),
104 'history' => $this->runner()->history(20),
108 private function apiStart():
void
110 $this->requireToken(
'api_start');
111 $data = $this->payload();
112 $profile = ($data[
'profile'] ??
'') ===
'quick' ?
'quick' :
'full';
113 $ids = is_array($data[
'test_ids'] ??
null) ? array_slice($data[
'test_ids'], 0, 500) : array();
114 $mode = count($ids) === 1 ?
'single' : ($ids !== array() ?
'selection' :
'complete');
117 $this->json(array(
'ok' => 1,
'run' =>
$run));
118 }
catch (\Throwable $e) {
119 http_response_code(400);
120 $this->json(array(
'ok' => 0,
'error' => $e->getMessage()));
124 private function apiExecute():
void
126 $this->requireToken(
'api_execute');
129 @set_time_limit(360);
130 $data = $this->payload();
132 $result = $this->runner()->executeRunTest(
133 (
string)($data[
'run_id'] ??
''),
134 (
string)($data[
'test_id'] ??
'')
136 $run = $this->runner()->loadRun((
string)($data[
'run_id'] ??
''));
137 $this->json(array(
'ok' => 1,
'result' =>
$result,
'run' =>
$run));
138 }
catch (\Throwable $e) {
139 http_response_code(400);
140 $this->json(array(
'ok' => 0,
'error' => $e->getMessage()));
144 private function apiFinish():
void
146 $this->requireToken(
'api_finish');
147 $data = $this->payload();
149 $run = $this->runner()->finishRun(
150 (
string)($data[
'run_id'] ??
''),
151 !empty($data[
'aborted'])
153 $this->json(array(
'ok' => 1,
'run' =>
$run,
'history' => $this->runner()->history(20)));
154 }
catch (\Throwable $e) {
155 http_response_code(400);
156 $this->json(array(
'ok' => 0,
'error' => $e->getMessage()));
160 private function apiBrowserResult():
void
162 $this->requireToken(
'api_browser_result');
163 $data = $this->payload();
165 $result = $this->runner()->recordBrowserTestResult(
166 (
string)($data[
'run_id'] ??
''),
167 (
string)($data[
'test_id'] ??
''),
168 is_array($data[
'result'] ??
null) ? $data[
'result'] : array()
170 $run = $this->runner()->loadRun((
string)($data[
'run_id'] ??
''));
171 $this->json(array(
'ok' => 1,
'result' =>
$result,
'run' =>
$run));
172 }
catch (\Throwable $e) {
173 http_response_code(400);
174 $this->json(array(
'ok' => 0,
'error' => $e->getMessage()));
178 private function apiRun():
void
180 $id = (string)
dbx()->get_modul_var(
'run_id',
'',
'parameter|max=40');
181 $run = $this->runner()->loadRun($id);
183 http_response_code(404);
184 $this->json(array(
'ok' => 0,
'error' =>
'Testlauf nicht gefunden.'));
186 $this->json(array(
'ok' => 1,
'run' =>
$run));
189 private function download():
void
191 $id = (string)
dbx()->get_modul_var(
'run_id',
'',
'parameter|max=40');
192 $path = $this->runner()->runLogPath($id);
193 if ($path ===
null) {
194 http_response_code(404);
195 echo
'Testprotokoll nicht gefunden.';
198 header(
'Content-Type: application/json; charset=utf-8');
199 header(
'Content-Disposition: attachment; filename="dbx-selftest-' . $id .
'.json"');
200 header(
'Content-Length: ' . (
string)filesize($path));
205 public function run(): string
207 $action = (string)
dbx()->get_modul_var(
'dbx_run1',
'dashboard',
'parameter');
221 case 'api_browser_result':
222 $this->apiBrowserResult();
231 return $this->dashboard();