406 lines
14 KiB
PHP
406 lines
14 KiB
PHP
<?php
|
|
// DEPENDENCIES
|
|
use severak\database\rows;
|
|
use severak\forms\form;
|
|
|
|
$dependencies['config'] = $config;
|
|
$singletons['pdo'] = function() {
|
|
$config = di('config');
|
|
return new PDO('sqlite:' . __DIR__ . '/' . $config['database']);
|
|
};
|
|
$singletons['rows'] = function(){
|
|
return new severak\database\rows(di('pdo'));
|
|
};
|
|
|
|
// ROUTY
|
|
|
|
// HP & LOGIN
|
|
route('', '/', function (){
|
|
// if (!user()) return redirect('/login/');
|
|
$rows = di('rows');
|
|
$Parsedown = new Parsedown();
|
|
$pois = $rows->more('poi', [], [], 999);
|
|
$geojson = pois2geojson($pois, $Parsedown);
|
|
return render('poi', ['geojson'=>$geojson]);
|
|
});
|
|
|
|
route('', '/poi/{slug}/', function ($req, $params){
|
|
$rows = di('rows');
|
|
$poi = $rows->one('poi', ['slug'=>$params['slug']]);
|
|
if (!$poi) return notFound();
|
|
$Parsedown = new Parsedown();
|
|
|
|
$poi['description'] = $Parsedown->text($poi['description']);
|
|
$poi['cheatsheet'] = $Parsedown->text($poi['cheatsheet']);
|
|
|
|
$pois = $rows->more('poi', [], [], 999);
|
|
$geojson = pois2geojson($pois, $Parsedown);
|
|
return render('poi', ['geojson'=>$geojson, 'poi'=>$poi]);
|
|
});
|
|
|
|
route('', '/login/', function ($req){
|
|
/** @var Psr\Http\Message\ServerRequestInterface $req */
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
$form = new form(['method'=>'POST']);
|
|
$form->field('username', ['required'=>true, 'label'=>'Jméno']);
|
|
$form->field('password', ['type'=>'password', 'required'=>true, 'label'=>'Heslo']);
|
|
$form->field('_login', ['type'=>'submit', 'label'=>'Přihlásit se']);
|
|
|
|
if ($req->getMethod()=='POST') {
|
|
$form->fill($req->getParsedBody());
|
|
if ($form->validate()) {
|
|
$uz = $rows->one('users', ['username'=>$form->values['username'], 'is_active'=>1]);
|
|
if (!$uz) {
|
|
$form->error('username', 'Uživatel nenalezen');
|
|
} elseif (password_verify($form->values['password'], $uz['password'])) {
|
|
unset($uz['password']);
|
|
$_SESSION['user'] = $uz;
|
|
return redirect('/');
|
|
} else {
|
|
$form->error('password', 'Špatné heslo.');
|
|
}
|
|
}
|
|
}
|
|
return render('form', ['form'=>$form]);
|
|
});
|
|
|
|
route('', '/logout/', function ($req){
|
|
unset($_SESSION['user']);
|
|
unset($_SESSION['flashes']);
|
|
return redirect('/');
|
|
});
|
|
|
|
route('', '/zmena-hesla/', function ($req){
|
|
if (!user()) return redirect('/login/');
|
|
$user = user();
|
|
/** @var Psr\Http\Message\ServerRequestInterface $req */
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
|
|
$form = new form(['method'=>'post']);
|
|
$form->field('password_current', ['required'=>true, 'type'=>'password', 'label'=>'Stávající heslo']);
|
|
$form->field('password', ['required'=>true, 'type'=>'password', 'label'=>'Nové heslo']);
|
|
$form->field('password_again', ['required'=>true, 'type'=>'password', 'label'=>'Nové heslo znovu']);
|
|
$form->field('_sbt', ['label'=>'Změnit heslo', 'type'=>'submit']);
|
|
|
|
$form->rule('password_again', function ($v, $o){
|
|
return $v==$o['password'];
|
|
}, 'Hesla se neshodují!');
|
|
|
|
$uz = $rows->one('users', $user['id']);
|
|
|
|
$form->rule('password_current', function ($v, $o) use ($uz) {
|
|
return password_verify($v, $uz['password']);
|
|
}, 'Špatné zadané současné heslo!');
|
|
|
|
if ($req->getMethod()=='POST' && $form->fill($req->getParsedBody()) && $form->validate()) {
|
|
$rows->update('users', [
|
|
'password'=>password_hash($form->values['password'], PASSWORD_DEFAULT)
|
|
], [
|
|
'id'=>$user['id']
|
|
]);
|
|
flash('Heslo změněno.');
|
|
return redirect('/');
|
|
}
|
|
|
|
return render('form', ['form'=>$form, 'title'=>'Změnit heslo']);
|
|
});
|
|
|
|
$singletons['poi_form'] = function () {
|
|
$form = new severak\forms\form(['method'=>'post']);
|
|
$form->field('name', ['label'=>'Název', 'required'=>true]);
|
|
$form->field('description', ['label'=>'Popis', 'type'=>'textarea']);
|
|
$form->field('cheatsheet', ['label'=>'Tahák', 'type'=>'textarea']);
|
|
$form->field('internal', ['label'=>'Poznámka', 'type'=>'textarea']);
|
|
$form->field('is_public', ['label'=>'Zveřejněno?', 'type'=>'checkbox']);
|
|
$form->field('lon', ['type'=>'hidden']);
|
|
$form->field('lat', ['type'=>'hidden']);
|
|
$form->field('_sbt', ['label'=>'Uložit?', 'type'=>'submit']);
|
|
|
|
$form->rule('lon', function ($v, $o) {
|
|
return !empty($o['lon']) && !empty($o['lat']);
|
|
}, 'Musí být vyplněny souřadnice');
|
|
|
|
return $form;
|
|
};
|
|
|
|
// správa POI
|
|
route('GET', '/pois/', function ($req){
|
|
return redirect('/pois/edit/');
|
|
});
|
|
|
|
route('GET', '/pois/edit/', function ($req){
|
|
if (!user()) return redirect('/login/');
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
$page = $_GET['page'] ?? 1;
|
|
$pois = $rows->page('poi', [], ['name'=>'asc'], $page, 30);
|
|
$pages = $rows->pages;
|
|
|
|
return render('poi_list', ['pois'=>$pois, 'pages'=>$pages, 'page'=>$page]);
|
|
});
|
|
|
|
route('', '/pois/add/', function ($req){
|
|
if (!user()) return redirect('/login/');
|
|
/** @var Psr\Http\Message\ServerRequestInterface $req */
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
/** @var severak\forms\form $form */
|
|
$form = di('poi_form');
|
|
|
|
if ($req->getMethod()=='POST') {
|
|
$form->fill($req->getParsedBody());
|
|
if ($form->validate()) {
|
|
$slug = slugify($form->values['name']);
|
|
$rows->insert('poi', [
|
|
'name'=>$form->values['name'],
|
|
'description'=>$form->values['description'],
|
|
'cheatsheet'=>$form->values['cheatsheet'],
|
|
'internal'=>$form->values['internal'],
|
|
'slug'=>$slug,
|
|
'lon'=>$form->values['lon'],
|
|
'lat'=>$form->values['lat'],
|
|
'is_public'=>$form->values['is_public'] ?? 0,
|
|
]);
|
|
return redirect('/poi/' . $slug . '/');
|
|
}
|
|
}
|
|
|
|
return render('form', ['form'=>$form, 'title'=>'Přidat položku']);
|
|
});
|
|
|
|
route('', '/pois/edit/{id}/', function ($req, $params){
|
|
if (!user()) return redirect('/login/');
|
|
/** @var Psr\Http\Message\ServerRequestInterface $req */
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
/** @var severak\forms\form $form */
|
|
$form = di('poi_form');
|
|
|
|
$item = $rows->one('poi', $params['id']);
|
|
if (!$item) return notFound();
|
|
$form->fill($item);
|
|
|
|
if ($req->getMethod()=='POST') {
|
|
$form->fill($req->getParsedBody());
|
|
if ($form->validate()) {
|
|
$slug = slugify($form->values['name']);
|
|
$rows->update('poi', [
|
|
'name'=>$form->values['name'],
|
|
'description'=>$form->values['description'],
|
|
'cheatsheet'=>$form->values['cheatsheet'],
|
|
'internal'=>$form->values['internal'],
|
|
'slug'=>$slug,
|
|
'lon'=>$form->values['lon'],
|
|
'lat'=>$form->values['lat'],
|
|
'is_public'=>$form->values['is_public'] ?? 0,
|
|
], $params['id']);
|
|
return redirect('/poi/' . $slug . '/');
|
|
}
|
|
}
|
|
|
|
return render('form', ['form'=>$form, 'title'=>'Upravit položku']);
|
|
});
|
|
|
|
// TODO - tohle nechceme přes GET
|
|
route('', '/sklad/smazat/{id}/', function ($req, $params){
|
|
if (!user()) return redirect('/login/');
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
$rows->update('items', ['is_active'=>0], ['id'=>$params['id'] ]);
|
|
return redirect('/sklad/');
|
|
});
|
|
|
|
|
|
|
|
// OBSLUHA
|
|
|
|
route('GET', '/obsluha/', function ($req){
|
|
if (!user()) return redirect('/login/');
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
$items = $rows->page('users', [], ['is_active'=>'desc', 'name'=>'asc']);
|
|
|
|
return render('users', ['users'=>$items]);
|
|
});
|
|
|
|
route('', '/obsluha/pridat/', function ($req){
|
|
if (!user()) return redirect('/login/');
|
|
$user = user();
|
|
if (!$user['is_superuser']) {
|
|
flash('Obsluhu může přidávat jen admin.', 'warning');
|
|
return redirect('/');
|
|
}
|
|
|
|
/** @var Psr\Http\Message\ServerRequestInterface $req */
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
|
|
$form = new form(['method'=>'post']);
|
|
$form->field('username', ['label'=>'Uživatelské jméno']);
|
|
$form->field('password', ['required'=>true, 'type'=>'password', 'label'=>'Heslo']);
|
|
$form->field('password_again', ['required'=>true, 'type'=>'password', 'label'=>'Heslo znovu']);
|
|
$form->field('name', ['required'=>true, 'type'=>'text', 'label'=>'Jméno']);
|
|
$form->field('card_id', ['type'=>'number', 'label'=>'Číslo členské karty', 'id'=>'qrcode']);
|
|
$form->field('_sbt', ['label'=>'Přidat', 'type'=>'submit']);
|
|
|
|
$form->rule('password_again', function ($v, $o){
|
|
return $v==$o['password'];
|
|
}, 'Hesla se neshodují!');
|
|
|
|
if ($req->getMethod()=='POST' && $form->fill($req->getParsedBody()) && $form->validate()) {
|
|
$duplicateUser = $rows->one('users', ['username'=>$form->values['username'] ]);
|
|
if ($duplicateUser) {
|
|
$form->error('username', 'Uživatel tohoto jména již v systému je.');
|
|
}
|
|
|
|
$memberId = null;
|
|
if ($form->values['card_id']) {
|
|
$card = $rows->one('cards', ['id'=>$form->values['card_id'], 'is_active'=>1]);
|
|
$memberId = $card['member_id'];
|
|
}
|
|
|
|
if ($form->isValid) {
|
|
$rows->insert('users', [
|
|
'username' => $form->values['username'],
|
|
'name' => $form->values['name'],
|
|
'password' => password_hash($form->values['password'], PASSWORD_DEFAULT),
|
|
'member_id'=> $memberId
|
|
]);
|
|
|
|
flash('Uživatel přidán.', 'success');
|
|
return redirect('/obsluha/');
|
|
}
|
|
}
|
|
|
|
return render('form', ['form'=>$form, 'title'=>'Přidat obsluhu']);
|
|
});
|
|
|
|
route('', '/obsluha/upravit/{id}/', function ($req, $params){
|
|
if (!user()) return redirect('/login/');
|
|
$user = user();
|
|
|
|
if (!$user['is_superuser']) {
|
|
flash('Obsluhu může upravovat jen admin.', 'warning');
|
|
return redirect('/');
|
|
}
|
|
|
|
$id = $params['id'];
|
|
|
|
/** @var Psr\Http\Message\ServerRequestInterface $req */
|
|
/** @var severak\database\rows $rows */
|
|
$rows = di('rows');
|
|
|
|
$form = new form(['method'=>'post']);
|
|
$form->field('username', ['label'=>'Uživatelské jméno']);
|
|
$form->field('password', ['type'=>'password', 'label'=>'Heslo']);
|
|
$form->field('password_again', ['type'=>'password', 'label'=>'Heslo znovu']);
|
|
$form->field('name', ['required'=>true, 'type'=>'text', 'label'=>'Jméno']);
|
|
$form->field('card_id', ['type'=>'number', 'label'=>'Číslo členské karty', 'id'=>'qrcode']);
|
|
$form->field('is_active', ['type'=>'checkbox', 'label'=>'Aktivní?']);
|
|
$form->field('is_superuser', ['type'=>'checkbox', 'label'=>'Je admin?']);
|
|
$form->field('note', ['type'=>'textarea', 'label'=>'Poznámka']);
|
|
$form->field('_sbt', ['label'=>'Uložit', 'type'=>'submit']);
|
|
|
|
$form->rule('password_again', function ($v, $o){
|
|
return $v==$o['password'];
|
|
}, 'Hesla se neshodují!');
|
|
|
|
if ($req->getMethod()=='POST' && $form->fill($req->getParsedBody())) {
|
|
$form->validate();
|
|
|
|
$duplicateUser = $rows->one('users', ['username'=>$form->values['username'] ]);
|
|
if ($duplicateUser && $duplicateUser['id']!=$id) {
|
|
$form->error('username', 'Uživatel tohoto jména již v systému je.');
|
|
}
|
|
|
|
if ($form->values['password'] && $form->values['password']!=$form->values['password_again']) {
|
|
$form->error('password', 'Hesla se musí shodovat!');
|
|
}
|
|
|
|
if ($form->isValid) {
|
|
$update = $form->values; // TODO tohle je prasárna
|
|
unset($update['id'], $update['password'], $update['password_again'], $update['card_id'], $update['_sbt']);
|
|
if ($form->values['password'] && $form->values['password']!=$form->values['password_again']) {
|
|
$update['password'] = password_hash($form->values['password'], PASSWORD_DEFAULT);
|
|
}
|
|
|
|
if ($form->values['card_id']) {
|
|
$card = $rows->one('cards', ['id'=>$form->values['card_id'], 'is_active'=>1]);
|
|
$update['member_id'] = $card['member_id'];
|
|
}
|
|
|
|
$rows->update('users', $update, $id);
|
|
|
|
flash('Uživatel upraven.', 'success');
|
|
return redirect('/obsluha/');
|
|
}
|
|
|
|
} else {
|
|
$editedUser = $rows->one('users', $id);
|
|
|
|
unset($editedUser['password']);
|
|
|
|
if ($editedUser['member_id']) {
|
|
$card = $rows->one('cards', ['member_id'=>$editedUser['member_id'], 'is_active'=>1]);
|
|
if ($card) {
|
|
$editedUser['card_id'] = $card['id'];
|
|
}
|
|
}
|
|
|
|
$form->fill($editedUser);
|
|
}
|
|
|
|
return render('form', ['form'=>$form, 'title'=>'Upravit obsluhu']);
|
|
});
|
|
|
|
function pois2geojson($pois, $Parsedown)
|
|
{
|
|
$geojson = ['type'=>'FeatureCollection', 'features'=>[]];
|
|
foreach ($pois as $poi) {
|
|
$geojson['features'][] = [
|
|
'type' => 'Feature',
|
|
'properties' => [
|
|
'name' => $poi['name'],
|
|
'description' => $Parsedown->text($poi['description']),
|
|
'cheatsheet' => $Parsedown->text($poi['cheatsheet']),
|
|
'slug' => $poi['slug'],
|
|
'id' => $poi['id'],
|
|
],
|
|
'geometry'=>[
|
|
'type'=>'Point',
|
|
'coordinates'=>[$poi['lon'], $poi['lat']]
|
|
]
|
|
];
|
|
}
|
|
return $geojson;
|
|
}
|
|
|
|
function slugify($text, $divider = '-')
|
|
{
|
|
// replace non letter or digits by divider
|
|
$text = preg_replace('~[^\pL\d]+~u', $divider, $text);
|
|
|
|
// transliterate
|
|
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
|
|
|
|
// remove unwanted characters
|
|
$text = preg_replace('~[^-\w]+~', '', $text);
|
|
|
|
// trim
|
|
$text = trim($text, $divider);
|
|
|
|
// remove duplicate divider
|
|
$text = preg_replace('~-+~', $divider, $text);
|
|
|
|
// lowercase
|
|
$text = strtolower($text);
|
|
|
|
if (empty($text)) {
|
|
return 'n-a';
|
|
}
|
|
|
|
return $text;
|
|
}
|