Obvody/app/Presentation/Administrace/AdministracePresenter.php

265 lines
8.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Presentation\Administrace;
use App\Model\LoginFacade;
use App\Model\SborFacade;
use App\Presentation\BasePresenter;
use Nette;
use Nette\Application\UI\Form;
use Nette\Application\UI\Multiplier;
use Nette\Database\Row;
use Nette\Http\FileUpload;
use Nette\Utils\ArrayHash;
final class AdministracePresenter extends BasePresenter
{
private string $stav = 'aktivni';
public function __construct(
private LoginFacade $uzivatele,
private SborFacade $sbor,
) {
}
protected function startup(): void
{
parent::startup();
if (!$this->uzivatele->jeAdmin((int) $this->getUser()->getId())) {
$this->error('Do administrace nemáte přístup.', Nette\Http\IResponse::S403_Forbidden);
}
}
public function actionDefault(?string $stav = null): void
{
if ($stav !== null && $stav !== 'aktivni' && $stav !== 'neaktivni') {
$this->redirect('this', ['stav' => 'aktivni']);
}
$this->stav = $stav === 'neaktivni' ? 'neaktivni' : 'aktivni';
}
public function renderDefault(): void
{
$uzivatele = [];
foreach ($this->uzivatele->getUzivatele($this->stav === 'aktivni') as $uzivatel) {
$uzivatele[] = (object) [
'id' => (int) $uzivatel->ID,
'jmeno' => (string) $uzivatel->JMENO,
'aktivni' => $this->jeAktivni($uzivatel->AKTIVNI),
'chraneny' => $this->uzivatele->jeChraneny($uzivatel),
];
}
$this->template->stav = $this->stav;
$this->template->uzivatele = $uzivatele;
$this->template->sbor = $this->sbor->getSbor();
}
protected function createComponentSborForm(): Form
{
$form = new Form;
$form->addUpload('soubor', 'Soubor KML')
->setRequired('Vyberte soubor KML.')
->setHtmlAttribute('accept', '.kml,application/vnd.google-earth.kml+xml');
$form->addSubmit('send', 'Nahrát');
$form->addProtection('Platnost formuláře vypršela, odešlete ho znovu.');
$form->onSuccess[] = $this->sborFormSucceeded(...);
return $form;
}
private function sborFormSucceeded(Form $form, ArrayHash $values): void
{
$soubor = $values->soubor;
if (!$soubor instanceof FileUpload || !$soubor->isOk()) {
$form->addError('Soubor se nepodařilo nahrát.');
return;
}
$pripona = strtolower(pathinfo($soubor->getUntrustedName(), PATHINFO_EXTENSION));
if ($pripona !== 'kml') {
$form->addError('Nahrajte soubor ve formátu KML.');
return;
}
$obsah = $soubor->getContents();
if (!is_string($obsah) || $obsah === '') {
$form->addError('Soubor KML je prázdný.');
return;
}
try {
$this->sbor->nahradZKml($obsah);
} catch (\InvalidArgumentException $e) {
$form->addError($e->getMessage());
return;
}
$this->flashMessage('Hranice sboru byly uloženy.');
$this->redirect('this');
}
protected function createComponentNovyForm(): Form
{
$form = new Form;
$form->addText('jmeno', 'Uživatel')
->setRequired('Zadejte uživatelské jméno.')
->setMaxLength(50);
$form->addPassword('heslo', 'Heslo')
->setRequired('Zadejte heslo.')
->setMaxLength(100);
$form->addPassword('hesloZnovu', 'Heslo znovu')
->setRequired('Zadejte heslo znovu.')
->addRule(Form::Equal, 'Hesla se neshodují.', $form['heslo']);
$form->addSubmit('send', 'Založit');
$form->addProtection('Platnost formuláře vypršela, odešlete ho znovu.');
$form->onSuccess[] = $this->novyFormSucceeded(...);
return $form;
}
private function novyFormSucceeded(Form $form, ArrayHash $values): void
{
$jmeno = trim((string) $values->jmeno);
$heslo = (string) $values->heslo;
if (!$this->platneJmeno($jmeno)) {
$form->addError('Jméno smí mít nejvýše 50 znaků a jen písmena, čísla, tečku, pomlčku a podtržítko.');
return;
}
if ($this->uzivatele->jeChraneneJmeno($jmeno)) {
$form->addError('Účet správce nelze založit znovu.');
return;
}
if (!$this->platneHeslo($form, $heslo)) {
return;
}
if (!$this->uzivatele->zaloz($jmeno, $heslo)) {
$form->addError('Uživatel s tímto jménem už existuje.');
return;
}
$this->flashMessage('Uživatel byl založen.');
$this->redirect('this', ['stav' => 'aktivni']);
}
protected function createComponentHesloForm(): Form
{
$form = new Form;
$form->addHidden('id')
->setRequired('Uživatel nenalezen.');
$form->addHidden('jmeno');
$form->addPassword('heslo', 'Nové heslo')
->setRequired('Zadejte nové heslo.')
->setMaxLength(100);
$form->addPassword('hesloZnovu', 'Nové heslo znovu')
->setRequired('Zadejte nové heslo znovu.')
->addRule(Form::Equal, 'Hesla se neshodují.', $form['heslo']);
$form->addSubmit('send', 'Uložit heslo');
$form->addProtection('Platnost formuláře vypršela, odešlete ho znovu.');
$form->onSuccess[] = $this->hesloFormSucceeded(...);
return $form;
}
private function hesloFormSucceeded(Form $form, ArrayHash $values): void
{
$heslo = (string) $values->heslo;
if (!$this->platneHeslo($form, $heslo)) {
return;
}
$uzivatel = $this->muzeUpravit((int) $values->id);
if ($uzivatel === null) {
$form->addError('Tomuto uživateli nelze změnit heslo.');
return;
}
if (!$this->uzivatele->zmenHeslo((int) $uzivatel->ID, $heslo)) {
$form->addError('Tomuto uživateli nelze změnit heslo.');
return;
}
$this->flashMessage('Heslo bylo změněno.');
$this->redirect('this');
}
protected function createComponentStav(): Multiplier
{
return new Multiplier(function (string $id): Form {
$form = new Form;
$form->addSubmit('send', 'Změnit stav');
$form->addProtection('Platnost formuláře vypršela, odešlete ho znovu.');
$form->onSuccess[] = function () use ($id): void {
$uzivatel = $this->muzeUpravit((int) $id);
if ($uzivatel === null) {
$this->flashMessage('Tomuto uživateli nelze změnit stav.', 'error');
$this->redirect('this');
}
$aktivni = !$this->jeAktivni($uzivatel->AKTIVNI);
if (!$this->uzivatele->nastavAktivni((int) $uzivatel->ID, $aktivni)) {
$this->flashMessage('Tomuto uživateli nelze změnit stav.', 'error');
$this->redirect('this');
}
$this->flashMessage($aktivni ? 'Uživatel byl aktivován.' : 'Uživatel byl zneaktivněn.');
$this->redirect('this', ['stav' => $aktivni ? 'aktivni' : 'neaktivni']);
};
return $form;
});
}
protected function createComponentSmazat(): Multiplier
{
return new Multiplier(function (string $id): Form {
$form = new Form;
$form->addSubmit('send', 'Smazat');
$form->addProtection('Platnost formuláře vypršela, odešlete ho znovu.');
$form->onSuccess[] = function () use ($id): void {
$uzivatel = $this->muzeUpravit((int) $id);
if ($uzivatel === null || !$this->uzivatele->smaz((int) $uzivatel->ID)) {
$this->flashMessage('Tohoto uživatele nelze smazat.', 'error');
$this->redirect('this');
}
$this->flashMessage('Uživatel byl smazán.');
$this->redirect('this');
};
return $form;
});
}
private function muzeUpravit(int $id): ?Row
{
$uzivatel = $this->uzivatele->get($id);
if ($uzivatel === null || $this->uzivatele->jeChraneny($uzivatel)) {
return null;
}
return $uzivatel;
}
private function platneHeslo(Form $form, string $heslo): bool
{
if (mb_strlen($heslo) < 4) {
$form->addError('Heslo musí mít alespoň 4 znaky.');
return false;
}
if (mb_strlen($heslo) > 100) {
$form->addError('Heslo je příliš dlouhé.');
return false;
}
return true;
}
private function platneJmeno(string $jmeno): bool
{
return (bool) preg_match('/^[\p{L}\p{N}._-]{1,50}$/u', $jmeno);
}
private function jeAktivni(mixed $hodnota): bool
{
return $hodnota === true || $hodnota === 1 || $hodnota === '1';
}
}