Obvody/app/Model/LogFacade.php

166 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Model;
use Nette\Database\Explorer;
use Nette\Security\User;
/**
* Textový záznam akcí přihlášeného uživatele.
* Uživatel je jen jméno z LOGIN, bez vazby na účet.
*/
final class LogFacade
{
public function __construct(
private Explorer $database,
private User $user,
) {
}
public function hranice(int $cislo): void
{
$this->zapis('Upraveny hranice obvodu č. ' . $cislo . '.');
}
public function prideleno(int $cislo, string $zvestovatel, \DateTimeInterface $den): void
{
$this->zapis(sprintf(
'Obvod č. %d přidělen zvěstovateli %s dne %s.',
$cislo,
$zvestovatel,
$den->format('j.n.Y'),
));
}
public function vraceno(int $cislo, string $zvestovatel, \DateTimeInterface $den): void
{
$this->zapis(sprintf(
'Obvod č. %d vrácen zvěstovatelem %s dne %s.',
$cislo,
$zvestovatel,
$den->format('j.n.Y'),
));
}
/**
* @param \DateTimeInterface|null $vraceno null, když záznam ještě nebyl vrácen
*/
public function upraven(int $cislo, string $zvestovatel, \DateTimeInterface $pridelen, ?\DateTimeInterface $vraceno): void
{
$this->zapis($this->textZaznamu('upraven', $cislo, $zvestovatel, $pridelen, $vraceno));
}
/**
* @param \DateTimeInterface|null $vraceno null, když záznam ještě nebyl vrácen
*/
public function smazan(int $cislo, string $zvestovatel, \DateTimeInterface $pridelen, ?\DateTimeInterface $vraceno): void
{
$this->zapis($this->textZaznamu('smazán', $cislo, $zvestovatel, $pridelen, $vraceno));
}
private function textZaznamu(
string $akce,
int $cislo,
string $zvestovatel,
\DateTimeInterface $pridelen,
?\DateTimeInterface $vraceno,
): string {
$vraceni = $vraceno === null
? 'nevráceno'
: 'vráceno ' . $vraceno->format('j.n.Y');
return sprintf(
'Záznam u obvodu č. %d %s. Zvěstovatel %s, přiděleno %s, %s.',
$cislo,
$akce,
$zvestovatel,
$pridelen->format('j.n.Y'),
$vraceni,
);
}
public function prejmenovan(string $puvodni, string $nove): void
{
$this->zapis('Zvěstovatel ' . $puvodni . ' přejmenován na ' . $nove . '.');
}
/**
* Záznamy jednoho měsíce, nejnovější první.
* Načte o jeden řádek víc, aby šlo poznat, jestli existuje další dávka.
*
* @return array{radky: list<\Nette\Database\Row>, dalsi: bool}
*/
public function getMesic(int $rok, int $mesic, int $od, int $limit): array
{
$od = max(0, $od);
$limit = max(1, $limit);
$zacatek = new \DateTimeImmutable(sprintf('%04d-%02d-01 00:00:00', $rok, $mesic));
$radky = $this->database->fetchAll(
'SELECT ID, UZIVATEL, DATUM, [TEXT]
FROM [LOG]
WHERE DATUM >= ? AND DATUM < ?
ORDER BY DATUM DESC, ID DESC
OFFSET ' . $od . ' ROWS FETCH NEXT ' . ($limit + 1) . ' ROWS ONLY',
$zacatek,
$zacatek->modify('+1 month'),
);
$dalsi = count($radky) > $limit;
if ($dalsi) {
array_pop($radky);
}
return ['radky' => $radky, 'dalsi' => $dalsi];
}
/**
* Roky, ve kterých je aspoň jeden záznam, plus aktuální a vybraný rok.
*
* @return list<int>
*/
public function getRoky(int $vybrany): array
{
$min = $this->database->fetchField('SELECT MIN(DATUM) FROM [LOG]');
$max = $this->database->fetchField('SELECT MAX(DATUM) FROM [LOG]');
$letos = (int) (new \DateTimeImmutable('today'))->format('Y');
$od = $min instanceof \DateTimeInterface ? (int) $min->format('Y') : $letos;
$do = $max instanceof \DateTimeInterface ? (int) $max->format('Y') : $letos;
$od = min($od, $letos, $vybrany);
$do = max($do, $letos, $vybrany);
$roky = [];
for ($rok = $do; $rok >= $od; $rok--) {
$roky[] = $rok;
}
return $roky;
}
private function zapis(string $text): void
{
$this->database->query(
'INSERT INTO [LOG] (UZIVATEL, DATUM, [TEXT]) VALUES (?, ?, ?)',
$this->jmenoUzivatele(),
new \DateTimeImmutable(),
$text,
);
}
private function jmenoUzivatele(): string
{
$identita = $this->user->getIdentity();
if ($identita instanceof UserIdentity && $identita->username !== '') {
return $identita->username;
}
$id = $this->user->getId();
$jmeno = $id === null
? null
: $this->database->fetchField('SELECT JMENO FROM [LOGIN] WHERE ID = ?', $id);
return is_string($jmeno) && $jmeno !== '' ? $jmeno : 'neznámý';
}
}