Obvody/app/Presentation/Logy/LogyPresenter.php

200 lines
5.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Presentation\Logy;
use App\Model\LogFacade;
use App\Model\LoginFacade;
use App\Presentation\BasePresenter;
use Nette;
use Nette\Database\Row;
final class LogyPresenter extends BasePresenter
{
private const DAVKA = 100;
/** @var array<int, string> */
private const MESICE = [
1 => 'leden',
2 => 'únor',
3 => 'březen',
4 => 'duben',
5 => 'květen',
6 => 'červen',
7 => 'červenec',
8 => 'srpen',
9 => 'září',
10 => 'říjen',
11 => 'listopad',
12 => 'prosinec',
];
private int $rok;
private int $mesic;
public function __construct(
private LoginFacade $uzivatele,
private LogFacade $log,
) {
}
protected function startup(): void
{
parent::startup();
if (!$this->uzivatele->jeAdmin((int) $this->getUser()->getId())) {
$this->error('K logům nemáte přístup.', Nette\Http\IResponse::S403_Forbidden);
}
}
public function actionDefault(?int $rok = null, ?int $mesic = null): void
{
$dnes = new \DateTimeImmutable('today');
$rok = $rok ?? (int) $dnes->format('Y');
$mesic = $mesic ?? (int) $dnes->format('n');
if (!$this->platneObdobi($rok, $mesic)) {
$this->redirect('this', [
'rok' => (int) $dnes->format('Y'),
'mesic' => (int) $dnes->format('n'),
]);
}
$this->rok = $rok;
$this->mesic = $mesic;
}
public function renderDefault(): void
{
$stranka = $this->log->getMesic($this->rok, $this->mesic, 0, self::DAVKA);
$logy = $this->priprav($stranka['radky']);
$this->template->rok = $this->rok;
$this->template->mesic = $this->mesic;
$this->template->nazevMesice = self::MESICE[$this->mesic];
$this->template->mesice = $this->mesiceProSablonu();
$this->template->roky = $this->rokyProSablonu();
$this->template->logy = $logy;
$this->template->pocet = count($logy);
$this->template->pocetText = $this->textPoctu(count($logy));
$this->template->dalsi = $stranka['dalsi'];
$this->template->dalsiUrl = $stranka['dalsi']
? $this->link('dalsi!', ['rok' => $this->rok, 'mesic' => $this->mesic, 'od' => count($logy)])
: null;
}
public function handleDalsi(int $rok, int $mesic, int $od = 0): void
{
if (!$this->platneObdobi($rok, $mesic) || $od < 0) {
$this->error('Neplatné období.', Nette\Http\IResponse::S400_BadRequest);
}
if (!$this->isAjax()) {
$this->redirect('default', ['rok' => $rok, 'mesic' => $mesic]);
}
$stranka = $this->log->getMesic($rok, $mesic, $od, self::DAVKA);
$logy = $this->priprav($stranka['radky']);
$this->sendJson([
'html' => $this->radkyHtml($logy),
'dalsi' => $stranka['dalsi'],
'pocet' => count($logy),
'url' => $stranka['dalsi']
? $this->link('dalsi!', ['rok' => $rok, 'mesic' => $mesic, 'od' => $od + count($logy)])
: null,
]);
}
private function textPoctu(int $pocet): string
{
$jednotky = $pocet % 10;
$desitky = $pocet % 100;
if ($jednotky === 1 && $desitky !== 11) {
return 'Zobrazen ' . $pocet . ' záznam.';
}
if ($jednotky >= 2 && $jednotky <= 4 && ($desitky < 12 || $desitky > 14)) {
return 'Zobrazeny ' . $pocet . ' záznamy.';
}
return 'Zobrazeno ' . $pocet . ' záznamů.';
}
private function platneObdobi(int $rok, int $mesic): bool
{
return $mesic >= 1 && $mesic <= 12 && $rok >= 2000 && $rok <= 2100;
}
/**
* @param list<Row> $radky
* @return list<object{datum: string, uzivatel: string, text: string}>
*/
private function priprav(array $radky): array
{
$logy = [];
foreach ($radky as $radek) {
$datum = $radek->DATUM instanceof \DateTimeInterface
? \DateTimeImmutable::createFromInterface($radek->DATUM)
: new \DateTimeImmutable((string) $radek->DATUM);
$logy[] = (object) [
'datum' => $datum->format('j. n. Y H:i'),
'uzivatel' => (string) $radek->UZIVATEL,
'text' => (string) $radek->TEXT,
];
}
return $logy;
}
/**
* @return list<object{nazev: string, url: string, aktivni: bool}>
*/
private function mesiceProSablonu(): array
{
$mesice = [];
foreach (self::MESICE as $cislo => $nazev) {
$mesice[] = (object) [
'nazev' => mb_convert_case($nazev, MB_CASE_TITLE, 'UTF-8'),
'url' => $this->link('default', ['rok' => $this->rok, 'mesic' => $cislo]),
'aktivni' => $cislo === $this->mesic,
];
}
return $mesice;
}
/**
* @return list<object{rok: int, url: string, aktivni: bool}>
*/
private function rokyProSablonu(): array
{
$roky = [];
foreach ($this->log->getRoky($this->rok) as $rok) {
$roky[] = (object) [
'rok' => $rok,
'url' => $this->link('default', ['rok' => $rok, 'mesic' => $this->mesic]),
'aktivni' => $rok === $this->rok,
];
}
return $roky;
}
/**
* @param list<object{datum: string, uzivatel: string, text: string}> $logy
*/
private function radkyHtml(array $logy): string
{
$sablona = $this->createTemplate();
$sablona->setFile(__DIR__ . '/radky.latte');
$sablona->logy = $logy;
ob_start();
try {
$sablona->render();
} catch (\Throwable $e) {
ob_end_clean();
throw $e;
}
return (string) ob_get_clean();
}
}