Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
82.17% |
106 / 129 |
|
57.14% |
4 / 7 |
CRAP | |
0.00% |
0 / 1 |
| HostController | |
82.17% |
106 / 129 |
|
57.14% |
4 / 7 |
37.80 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| index | |
100.00% |
45 / 45 |
|
100.00% |
1 / 1 |
2 | |||
| view | |
70.59% |
24 / 34 |
|
0.00% |
0 / 1 |
8.25 | |||
| create | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| update | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
4 | |||
| delete | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
| formatHostRow | |
76.00% |
19 / 25 |
|
0.00% |
0 / 1 |
18.11 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace App\Web\Controller; |
| 6 | |
| 7 | use App\Domain\Host\Repository\HostApiConfigRepository; |
| 8 | use App\Domain\Host\Repository\HostDbConfigRepository; |
| 9 | use App\Domain\Host\Repository\HostRecordRepository; |
| 10 | use App\Domain\Host\Service\HostConnectionCheckerInterface; |
| 11 | use App\Domain\Shared\Query\GridQuerySpecification; |
| 12 | use App\Infrastructure\Shared\Query\GridQueryBuilder; |
| 13 | use App\Shared\Host\TablePrefixResolver; |
| 14 | use App\Shared\UI\ListView\ListViewData; |
| 15 | use Psr\Http\Message\ResponseInterface; |
| 16 | use Psr\Http\Message\ServerRequestInterface; |
| 17 | use Yiisoft\Yii\View\Renderer\WebViewRenderer; |
| 18 | |
| 19 | class HostController |
| 20 | { |
| 21 | private const VIEW_INDEX = '//host/index.twig'; |
| 22 | private const STATUS_NO_CONFIG = '⚪ Brak konfig.'; |
| 23 | |
| 24 | public function __construct(private WebViewRenderer $viewRenderer) |
| 25 | { |
| 26 | $this->viewRenderer = $viewRenderer->withControllerName('host'); |
| 27 | } |
| 28 | |
| 29 | public function index( |
| 30 | ServerRequestInterface $request, |
| 31 | HostRecordRepository $repository, |
| 32 | HostApiConfigRepository $apiRepo, |
| 33 | HostDbConfigRepository $dbRepo, |
| 34 | HostConnectionCheckerInterface $checker, |
| 35 | GridQueryBuilder $queryBuilder, |
| 36 | TablePrefixResolver $prefixResolver |
| 37 | ): ResponseInterface { |
| 38 | $allowedColumns = [ |
| 39 | 'name' => 'name', |
| 40 | 'label' => 'label', |
| 41 | 'db_prefix' => 'db_prefix', |
| 42 | 'type' => 'type', |
| 43 | 'url' => 'url', |
| 44 | 'created_at' => 'created_at', |
| 45 | ]; |
| 46 | |
| 47 | /** @var array<string, mixed> $queryParams */ |
| 48 | $queryParams = $request->getQueryParams(); |
| 49 | $spec = new GridQuerySpecification($queryParams, $allowedColumns, 'created_at', 'DESC'); |
| 50 | $targetTable = $prefixResolver->resolve('hosts_records'); |
| 51 | $queryResult = $queryBuilder->fetchData($targetTable, $spec, 'created_at', 'DESC'); |
| 52 | |
| 53 | $rawRows = $queryResult['items']; |
| 54 | $items = []; |
| 55 | foreach ($rawRows as $row) { |
| 56 | /** @var array<string, mixed> $row */ |
| 57 | $items[] = $this->formatHostRow($row, $apiRepo, $dbRepo, $checker); |
| 58 | } |
| 59 | |
| 60 | $totalItems = $queryResult['totalCount']; |
| 61 | |
| 62 | $listView = new ListViewData( |
| 63 | items: $items, |
| 64 | columns: [ |
| 65 | 'name' => 'Nazwa', |
| 66 | 'label' => 'Etykieta', |
| 67 | 'db_prefix' => 'Prefix Bazy (Klient)', |
| 68 | 'type' => 'Typ', |
| 69 | 'url' => 'Adres URL', |
| 70 | 'db_status' => 'Baza danych (Status)', |
| 71 | 'api_status' => 'API (Status)', |
| 72 | 'created_at' => 'Utworzono', |
| 73 | ], |
| 74 | currentPage: $spec->getPage(), |
| 75 | pageSize: $spec->getPageSize(), |
| 76 | totalItems: $totalItems, |
| 77 | sortField: $spec->getSortField(), |
| 78 | sortDirection: $spec->getSortDirection(), |
| 79 | filterParams: $spec->getFilters(), |
| 80 | viewRoute: 'host/view', |
| 81 | updateRoute: 'host/update', |
| 82 | deleteRoute: 'host/delete', |
| 83 | tableExists: (bool) ($queryResult['tableExists'] ?? true), |
| 84 | tableName: (string) ($queryResult['tableName'] ?? $targetTable) |
| 85 | ); |
| 86 | |
| 87 | return $this->viewRenderer->render(self::VIEW_INDEX, [ |
| 88 | 'listView' => $listView, |
| 89 | 'title' => 'Zarządzanie Hostami', |
| 90 | ]); |
| 91 | } |
| 92 | |
| 93 | public function view( |
| 94 | ServerRequestInterface $request, |
| 95 | HostRecordRepository $repository, |
| 96 | HostApiConfigRepository $apiRepo, |
| 97 | HostDbConfigRepository $dbRepo, |
| 98 | HostConnectionCheckerInterface $checker |
| 99 | ): ResponseInterface { |
| 100 | /** @var array<string, mixed> $params */ |
| 101 | $params = $request->getQueryParams(); |
| 102 | $id = is_string($params['id'] ?? null) ? (string) $params['id'] : ''; |
| 103 | $host = $repository->findById($id); |
| 104 | |
| 105 | if ($host === null) { |
| 106 | return $this->viewRenderer->render(self::VIEW_INDEX, [ |
| 107 | 'title' => 'Host nie znaleziony', |
| 108 | 'error' => 'Podany host nie istnieje.', |
| 109 | ]); |
| 110 | } |
| 111 | |
| 112 | $dbConfig = $dbRepo->findByHostId($host->getId()); |
| 113 | $apiConfig = $apiRepo->findByHostId($host->getId()); |
| 114 | |
| 115 | $dbStatusHtml = self::STATUS_NO_CONFIG; |
| 116 | if ($dbConfig !== null) { |
| 117 | $dbStatusHtml = $checker->checkDbConnection($dbConfig) |
| 118 | ? '<span class="badge bg-success-subtle text-success-emphasis rounded-pill px-2.5 py-1 fs-7">🟢 OK</span>' |
| 119 | : '<span class="badge bg-danger-subtle text-danger-emphasis rounded-pill px-2.5 py-1 fs-7">🔴 Błąd</span>'; |
| 120 | } |
| 121 | |
| 122 | $apiStatusHtml = self::STATUS_NO_CONFIG; |
| 123 | if ($apiConfig !== null) { |
| 124 | $apiStatusHtml = $checker->checkApiConnection($apiConfig) |
| 125 | ? '<span class="badge bg-success-subtle text-success-emphasis rounded-pill px-2.5 py-1 fs-7">🟢 OK</span>' |
| 126 | : '<span class="badge bg-danger-subtle text-danger-emphasis rounded-pill px-2.5 py-1 fs-7">🔴 Błąd</span>'; |
| 127 | } |
| 128 | |
| 129 | return $this->viewRenderer->render('//host/view.twig', [ |
| 130 | 'host' => [ |
| 131 | 'id' => $host->getId(), |
| 132 | 'name' => $host->getName(), |
| 133 | 'label' => $host->getLabel(), |
| 134 | 'db_prefix' => $host->getDbPrefix(), |
| 135 | 'type' => $host->getType(), |
| 136 | 'url' => $host->getUrl(), |
| 137 | ], |
| 138 | 'dbStatus' => $dbStatusHtml, |
| 139 | 'apiStatus' => $apiStatusHtml, |
| 140 | 'createdAt' => date('Y-m-d H:i:s', $host->getCreatedAt()), |
| 141 | 'title' => 'Podgląd Hosta: ' . $host->getName(), |
| 142 | ]); |
| 143 | } |
| 144 | |
| 145 | public function create(ServerRequestInterface $request): ResponseInterface |
| 146 | { |
| 147 | $_ = $request->getQueryParams(); |
| 148 | return $this->viewRenderer->render('//host/create.twig', [ |
| 149 | 'title' => 'Dodaj Nowy Host', |
| 150 | ]); |
| 151 | } |
| 152 | |
| 153 | public function update( |
| 154 | ServerRequestInterface $request, |
| 155 | HostRecordRepository $repository |
| 156 | ): ResponseInterface { |
| 157 | /** @var array<string, mixed> $params */ |
| 158 | $params = $request->getQueryParams(); |
| 159 | $id = is_string($params['id'] ?? null) ? (string) $params['id'] : ''; |
| 160 | $host = $repository->findById($id); |
| 161 | |
| 162 | return $this->viewRenderer->render('//host/update.twig', [ |
| 163 | 'host' => $host !== null ? [ |
| 164 | 'id' => $host->getId(), |
| 165 | 'name' => $host->getName(), |
| 166 | 'label' => $host->getLabel(), |
| 167 | 'db_prefix' => $host->getDbPrefix(), |
| 168 | 'type' => $host->getType(), |
| 169 | 'url' => $host->getUrl(), |
| 170 | ] : null, |
| 171 | 'title' => 'Edycja Hosta: ' . ($host !== null ? $host->getName() : ''), |
| 172 | ]); |
| 173 | } |
| 174 | |
| 175 | public function delete( |
| 176 | ServerRequestInterface $request, |
| 177 | HostRecordRepository $repository |
| 178 | ): ResponseInterface { |
| 179 | /** @var array<string, mixed> $params */ |
| 180 | $params = $request->getQueryParams(); |
| 181 | $id = is_string($params['id'] ?? null) ? (string) $params['id'] : ''; |
| 182 | $repository->delete($id); |
| 183 | |
| 184 | return $this->viewRenderer->render(self::VIEW_INDEX, [ |
| 185 | 'title' => 'Zarządzanie Hostami', |
| 186 | 'success' => 'Host został usunięty.', |
| 187 | ]); |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * @param array<string, mixed> $row |
| 192 | * @return array<string, mixed> |
| 193 | */ |
| 194 | private function formatHostRow( |
| 195 | array $row, |
| 196 | HostApiConfigRepository $apiRepo, |
| 197 | HostDbConfigRepository $dbRepo, |
| 198 | HostConnectionCheckerInterface $checker |
| 199 | ): array { |
| 200 | $hostId = is_string($row['id'] ?? null) ? (string) $row['id'] : ''; |
| 201 | $dbConfig = $dbRepo->findByHostId($hostId); |
| 202 | $apiConfig = $apiRepo->findByHostId($hostId); |
| 203 | |
| 204 | $dbStatusHtml = self::STATUS_NO_CONFIG; |
| 205 | if ($dbConfig !== null) { |
| 206 | $dbStatusHtml = $checker->checkDbConnection($dbConfig) |
| 207 | ? '<span class="badge bg-success">🟢 OK</span>' |
| 208 | : '<span class="badge bg-danger">🔴 Błąd</span>'; |
| 209 | } |
| 210 | |
| 211 | $apiStatusHtml = self::STATUS_NO_CONFIG; |
| 212 | if ($apiConfig !== null) { |
| 213 | $apiStatusHtml = $checker->checkApiConnection($apiConfig) |
| 214 | ? '<span class="badge bg-success">🟢 OK</span>' |
| 215 | : '<span class="badge bg-danger">🔴 Błąd</span>'; |
| 216 | } |
| 217 | |
| 218 | $createdAt = isset($row['created_at']) && is_numeric($row['created_at']) ? (int) $row['created_at'] : time(); |
| 219 | |
| 220 | return [ |
| 221 | 'id' => $hostId, |
| 222 | 'name' => is_string($row['name'] ?? null) ? (string) $row['name'] : '', |
| 223 | 'label' => isset($row['label']) && is_string($row['label']) ? $row['label'] : '-', |
| 224 | 'db_prefix' => isset($row['db_prefix']) && is_string($row['db_prefix']) ? $row['db_prefix'] : 'c01', |
| 225 | 'type' => is_string($row['type'] ?? null) ? (string) $row['type'] : '', |
| 226 | 'url' => is_string($row['url'] ?? null) ? (string) $row['url'] : '', |
| 227 | 'db_status' => $dbStatusHtml, |
| 228 | 'api_status' => $apiStatusHtml, |
| 229 | 'created_at' => date('Y-m-d H:i:s', $createdAt), |
| 230 | ]; |
| 231 | } |
| 232 | } |