WIP: editace POI a detail POI na webu.

This commit is contained in:
severak 2021-07-18 14:49:03 +02:00
parent 6cddfd786b
commit d3c14def4e
4 changed files with 2115 additions and 39 deletions

116
app.php
View File

@ -18,27 +18,26 @@ $singletons['rows'] = function(){
route('', '/', function (){
// if (!user()) return redirect('/login/');
$rows = di('rows');
$Parsedown = new Parsedown();
$pois = $rows->more('poi', [], [], 999);
$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'])
],
'geometry'=>[
'type'=>'Point',
'coordinates'=>[$poi['lon'], $poi['lat']]
]
];
}
$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 */
@ -109,16 +108,20 @@ route('', '/zmena-hesla/', function ($req){
});
$singletons['poi_form'] = function () {
$form = new severak\forms\form();
$form->field('name', ['label'=>'Název']);
$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('lan', ['type'=>'hidden']);
$form->field('lot', ['type'=>'hidden']);
$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;
};
@ -149,15 +152,18 @@ route('', '/pois/add/', function ($req){
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'=>slugify($form->values['name']),
'slug'=>$slug,
'lon'=>$form->values['lon'],
'lat'=>$form->values['lat'],
'is_public'=>$form->values['is_public'] ?? 0,
]);
return redirect('/pois/edit/');
return redirect('/poi/' . $slug . '/');
}
}
@ -179,15 +185,18 @@ route('', '/pois/edit/{id}/', function ($req, $params){
if ($req->getMethod()=='POST') {
$form->fill($req->getParsedBody());
if ($form->validate()) {
/*$rows->update('items', [
$slug = slugify($form->values['name']);
$rows->update('poi', [
'name'=>$form->values['name'],
'price'=>$form->values['price'],
'note'=>$form->values['note'],
'ord'=>$form->values['ord'],
'amount'=>$form->values['amount'],
'is_amount_tracked'=>$form->values['is_amount_tracked'],
'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('/sklad/');*/
return redirect('/poi/' . $slug . '/');
}
}
@ -345,3 +354,52 @@ route('', '/obsluha/upravit/{id}/', function ($req, $params){
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;
}

1946
static/Leaflet.Editable.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,72 @@ $F = new severak\forms\html($form);
echo $F->open();
foreach ($F->fields as $fieldName) {
if ($form->fields[$fieldName]['type']=='submit' && isset($form->fields['lon']) && isset($form->fields['lat'])) {
echo <<<MAP
<div class="field">
<div id="map"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
<script src="https://cdn.maptiler.com/mapbox-gl-js/v1.5.1/mapbox-gl.js"></script>
<script src="https://cdn.maptiler.com/mapbox-gl-leaflet/latest/leaflet-mapbox-gl.js"></script>
<script src="/static/Leaflet.Editable.js"></script>
<script src="/static/leaflet-sidebar.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css" />
<link rel="stylesheet" href="https://cdn.maptiler.com/mapbox-gl-js/v1.5.1/mapbox-gl.css" />
<style>
#map {
height: 500px;
}
</style>
<script>
function webgl_support() {
try {
var canvas = document.createElement('canvas');
return !!window.WebGLRenderingContext &&
(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
} catch (e) {
return false;
}
return false;
}
function detectMob() {
return ( ( window.innerWidth <= 800 ) && ( window.innerHeight <= 600 ) );
}
var lon = document.getElementById('form_lon').value;
var lat = document.getElementById('form_lat').value;
if (lon == 0 && lat ==0) {
lat = 50.08536; lon = 14.42040;
}
var map = L.map('map', {editable: true}).setView([lat, lon], 15);
if (!webgl_support() || detectMob()) {
var OpenStreetMap_Mapnik = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
} else {
var gl = L.mapboxGL({
attribution: "\u003ca href=\"https://svita.cz/\"\u003eSvita.cz\u003c/a\u003e \u003ca href=\"https://www.maptiler.com/copyright/\" target=\"_blank\"\u003e\u0026copy; MapTiler\u003c/a\u003e \u003ca href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\"\u003e\u0026copy; OpenStreetMap contributors\u003c/a\u003e",
style: 'https://api.maptiler.com/maps/28280352-f69a-45fd-8dd7-2f178d7ed64f/style.json?key=lFBi7gs1S6TyJPtVVvOX'
}).addTo(map);
}
var marker = L.marker([lat, lon]).addTo(map);
marker.enableEdit();
marker.on('editable:dragend', function(evt) {
if (evt.distance > 0) {
var newCoords = evt.layer._latlng;
document.getElementById('form_lat').value = newCoords.lat;
document.getElementById('form_lon').value = newCoords.lng;
}
})
</script>
MAP;
}
echo '<div class="field">';

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php if (isset($title)) echo $title . ' - ' ; ?>Průvodce</title>
<title><?php if (isset($poi['name'])) echo $poi['name'] . ' - ' ; ?>průvodce Matička Metropolis</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="/static/uboot.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
@ -39,17 +39,23 @@
<div class="sidebar-content">
<div class="sidebar-pane" id="home">
<h1 class="sidebar-header">
<span id="article-name">Turistický průvodce</span>
<span id="article-name"><?php if (isset($poi['name'])) { echo $poi['name']; } else { echo'Turistický průvodce'; } ?></span>
<span class="sidebar-close"><i class="fa fa-caret-left"></i></span>
</h1>
<div id="article-text">
<?php if (isset($poi['description'])) { echo $poi['description']; } else { ?>
<p>Matička Metropolis...</p>
<p>Stránka je v přípravě.</p>
<?php } ?>
</div>
<div id="article-cheat">
<?php if (isset($poi['description'])) { echo $poi['cheatsheet']; } ?>
</div>
<a href="#" id="article-link">odkaz na stránku</a>
<a href="#" id="article-edit-link" <?php if (!user()) echo 'style="display: none;"'; ?>>upravit</a>
</div>
</div>
</div>
@ -77,7 +83,7 @@ function detectMob() {
whenReady(function () {
var map = L.map('map').setView([50.08536, 14.42040], 15);
var map = L.map('map').setView([<?php if (isset($poi['lon'])) { echo $poi['lat'] . ',' . $poi['lon']; } else { echo '50.08536, 14.42040';} ?>], 15);
if (!webgl_support() || detectMob()) {
var OpenStreetMap_Mapnik = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
@ -100,12 +106,12 @@ whenReady(function () {
document.getElementById('article-name').innerText = layer.layer.feature.properties.name;
document.getElementById('article-text').innerHTML = layer.layer.feature.properties.description;
document.getElementById('article-cheat').innerHTML = layer.layer.feature.properties.cheatsheet;
document.getElementById('article-link').href = '/poi/' + layer.layer.feature.properties.slug + '/';
document.getElementById('article-edit-link').href = '/pois/edit/' + layer.layer.feature.properties.id + '/';
sidebar.open('home');
}).addTo(map);
<?php if (isset($poi['name'])) { ?>sidebar.open('home');<?php } ?>
});