Alter Version

This commit is contained in:
Walter Hupfeld 2024-02-16 15:35:01 +01:00
parent 6e85cec1da
commit 0df6729f8b
393 changed files with 173746 additions and 6 deletions

22
LICENSE
View File

@ -1,7 +1,21 @@
Copyright (c) <year> <owner>. All rights reserved.
MIT License
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Copyright (c) 2021 Walter Hupfeld
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

116
README.md
View File

@ -1,3 +1,115 @@
# melder
# Ideenmelder
Die Anwendung ermöglicht die Markierung von Standorten in einem begrenzten Bezirk (Stadt Hamm). Die Eingaben können beschrieben und bewertet werden. Das Hochladen von Bildern und das Kommentieren von Beiträgen ist möglich.
Die Idee zu dieser Anwendung kam durch einen Artikel in der ADFC-Zeitschrift Radwelt zu Ibbenbüren, wo Vorschläge zur Verkehrsinfrastruktur über eine Webanwendung erfasst wurden. Ich habe diese Idee übernommen und neu programmiert. Eine Demoanwendung findet man unter https://karte.hpadm.de (Login: admin Passwort: testtest)
Es sind aus meiner Sicht aber auch viele andere Anwendungsmöglichkeiten denkbar, z.B. Erfassung/Meldung von Eichenprozessionsspinnern, Markierung/Erfassung von Stromtankstellen etc..
## Installation
### Installation der Andwendung
Die Anwendung verfügt über ein Setup, das die Datenbank und fehlende Verzeichnisse anlegt, einen Nutzeraccount anlegt und die Anpassung der Texte ermöglicht.
### Konfiguration
Nach Installation können über die Konfiguration jederzeit die Parameter angepasst werden.
Folgende Funktionalitäten können an- bzw. abgeschaltet werden:
* Userinformationen (Altersklassen und überwiegend benutztes Verkehrsmittel)
* Rating (Positive und negative Bewertung)
* Hochladen von Bildern (erlaubt jpg/gif/png)
* Kommentare
### Reverse Georeferenzierung
Aus den übermittelten Geodaten wird die Adresse ermittelt. Dazu wird der Dienst https://locationiq.com verwendet. Die Adressen werden nur im Backend angezeigt, um die Auswertung der Daten zu erleichtern.
Für locationiq.com muss ein Api-Key beantragt werden. Dieser ist in der Datei /lib/geocoding.php einzutragen. Für die Georeferenzierung kann auch
---
## Versionen
### Version 2.2
* Behandlung der Eingaben mit Zeilenumbruch, Anführungszeichen und Hochkommas
* Die Konfiguration wird jetzt in der Datenbank gespeichert.
* Bei der Eingabe werden die Adressen georeferenziert (reverse), d.h. zum Standort wird eine Adresse ermittelt. Das ist nur im Backend sichtbar und dient zur Auswertung der Daten.
* Im Backend können jetzt Einträge bearbeitet werden (Änderung der Beschreibung, Änderung der Mängelkategorie und Hochladen von Bildern).
---
## Verwendete Bibliotheken
Die verwendeten Bibliotheken:
Die Speicherung erfolgt in einer SQlite-Datenbank im Verzeichnis /db. Sie wird während des Setups automtisch angelelgt. Zum Backup kann man die Datei locations.db einfach speichern.
### JQuery
Javacript-Framework
* https://jquery.com/
* Lizenz: MIT
### Bootstrap 4
CSS-Framework
* https://getbootstrap.com/
* Lizenz: MIT
### Leaflet
JS-Framwork für GIS-Anwendungen (Openstreetmap)
* https://leafletjs.com
* 2-clause BSD License
#### Leaflet-Ajax
Bibliothek, um Geojson-Datein per Ajax zu laden. Kann eigentlich durch JQuery-Ajax ersetzt werden.
* https://github.com/calvinmetcalf/leaflet-ajax
* Lizenz: MIT
#### Leaflet-Awesome-Markers
Ermöglicht, die Marker mit Fontawesom-Symbolen zu gestalten. die Bibliothek ist veraltet und bietet nur Zugriff auf die Fontawesome 4.x und nicht auf die neue Version 5.x.. Daher sollte sie eigentlich mal angepasst werden.
* https://github.com/lvoogdt/Leaflet.awesome-markers
* https://fontawesome.com/
* Lizenz: MIT
#### Leaflet-Snogylop
Erweiterung vom Leaflet um ein Polygon zu invertieren.
* https://github.com/ebrelsford/Leaflet.snogylop
* Lizenz: MIT
### Lightbox
Zur Darstellung von Bildern
* https://lokeshdhakar.com/projects/lightbox2/
* Lizenz: MIT
### Datatable
Darstellung der Tabelle
* https://datatables.net
* Lizenz: MIT
### Shapefile
Export von Shape-Files
* https://gasparesganga.com/labs/php-shapefile/
* Lizenz: MIT
## Improvements
* Rating durch Cookie absichern, so dass nicht zwei mal während einer Sitzung ein Maker betätigit werden kann.
* Alert nach Rating überarbeiten (z.B. mit Bootstrap)
Applikation zur georeferenzierten Meldung von Hindernissen, etc.

24
admin/alter_table.php Normal file
View File

@ -0,0 +1,24 @@
<?php
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
date_default_timezone_set('UTC');
const DB_FILENAME = "../db/locations.db";
$db = new SQLite3(DB_FILENAME);
$strSQL="ALTER TABLE location ADD COLUMN defect INTEGER";
$db->exec($strSQL);
$db->exec("CREATE TABLE IF NOT EXISTS user(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT,
passwordhash TEXT,
lastlogin TEXT DEFAULT CURRENT_TIMESTAMP,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)");
header("Location: configuration.php");

174
admin/configuration.php Normal file
View File

@ -0,0 +1,174 @@
<?php
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$dbFilename = "../db/locations.db";
require_once("../config.php");
$boolError=false;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/bootstrap.min.css" />
<link href="../css/font-awesome.min.css" rel="stylesheet">
<script src="../js/jquery.min.js"></script>
<title>Konfigruation</title>
<style>
.leftlabel { width: 10em;}
input[type="text"] { width: 18em;}
input.wide {width: 24em;}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Administration <?= $strTitle ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbars" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="index.php">Liste <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link active" href="configuration.php">Konfiguration </a>
</li>
<li class="nav-item">
<a class="nav-link" href="geocoding.php">Addressen ermitteln </a>
</li>
<li class="nav-item">
<a class="nav-link" href="export.php">Export </a>
</li>
<li class="nav-item">
<a class="nav-link" href="password.php">Passwort ändern </a>
</li>
</ul>
<div>
<ul class="navbar-nav mr-auto right">
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout (<?=$strLoginName?>)</a>
</li>
</ul>
</div>
</nav>
<!-- Ende Navbar -->
<div class="container" style="margin-top:5em;">
<h1>Konfiguration</h1>
<form method="post" id="myform" action="configuration_chk.php">
<div class="row">
<div class="col-md-7 col-lg-7">
<div class="card">
<div class="card-header">
<h3>Dateneingabe aktivieren</h3>
</div>
<div class="card-body">
<input type="checkbox" id="active" name="active" <?= ($boolActive) ? "checked=\"checked\"" :"" ?> >
<label for="active">Dateneingabe aktivieren</label><br>
</div>
</div>
<br>
<div class="card">
<div class="card-header">
<h3>Konfiguration</h3>
</div>
<div class="card-body">
<input type="checkbox" id="fileupload" name="fileupload" <?= ($boolUpload) ? "checked=\"checked\"" :"" ?> >
<label for="fileupload">Bilder hochladen erlauben</label><br>
<input type="checkbox" id="rating" name="rating" <?= ($boolRating) ? "checked=\"checked\"" :"" ?>>
<label for="rating"> Bewertungungen erlauben</label><br>
<input type="checkbox" id="comment" name="comment" <?= ($boolComment) ? "checked=\"checked\"" :"" ?> >
<label for="comment">Kommentare erlauben</label><br>
<input type="checkbox" id="defect" name="defect" <?= ($boolDefect) ? "checked=\"checked\"" :"" ?> >
<label for="defect">Mängelkategrien einblenden</label><br>
<input type="checkbox" id="userinfo" name="userinfo" <?= ($boolUserinfo) ? "checked=\"checked\"" :"" ?> >
<label for="userinfo">Nutzerinformation (Alter/Verkehrsmittel)</label>
<br>
<label class="leftlabel">Uplaod-Pfad:</label>
<input type="text" class="wide" name="uploaddir" id="uploaddir" value="<?=$uploaddir?>">
</div>
</div>
<br>
<div class="card">
<div class="card-header">
<h3>Karteninfo</h3>
</div>
<div class="card-body">
<h4>Stadt oder Kreis</h4>
<label class="leftlabel">Stadt/Kreis: </label>
<input type="text" name="district" id="district" value="<?=$strStadt?>" >
<h4>Kartenzentrum</h4>
<div class="small">Hier liegt das Zentrum der Karte und es erscheint der Info-Marker.</div>
<label class="leftlabel">Latitude:</label><input type="text" name="lat" id="lat" value="<?=$numInfoLat?>"><br>
<label class="leftlabel">Longitude:</label><input type="text" name="lng" id="lng" value="<?=$numInfoLng?>"><br>
<div class="small">Zoom-Faktor beim Start der Karte.</div>
<label class="leftlabel">Startzoom:</label><input type="text" name="zoom" id="zoom" value="<?=$numZoom?>">
<h4>GeoJson</h4>
<p>Die Datei kann man von folgender Adresse laden und ins Vezeichnis /geojson kopieren:
<a href="https://public.opendatasoft.com/explore/dataset/landkreise-in-germany/export/">public.opendatasoft.com</a>
</p>
<label class="leftlabel">GeoJson-Datei: </label><input type="text" name="geojson" id="geojson" value="<?=$fileGeojson?>">
</div>
</div>
<br>
<div class="card">
<div class="card-header">
<h3>Anbieterinformation</h3>
</div>
<div class="card-body">
<label class="leftlabel">Titel:</label><input type="text" name="title" id="title" value="<?=$strTitle?>"><br>
<label class="leftlabel">Kontakt-Email:</label><input type="text" name="contactEmail" id="contactEmail" value="<?=$contactEmail?>"><br>
<label class="leftlabel">Logo:</label><input type="text" name="logo" id="logo" value="<?=$strLogo?>"><br>
<label class="leftlabel">Url:</label><input type="text" class="wide" name="url" id="url" value="<?=$strUrl?>"><br>
<label class="leftlabel">Url-Text:</label><input type="text" class="wide" name="urlBez" id="urlBez" value="<?=$strUrlBez?>"><br>
<label>Impressum: (HTML erlaubt)</label>
<textarea id="impressum" name="impressum" rows="8" style="width:35em;"><?= stripslashes($strImpressum) ?></textarea>
</div>
</div>
<br>
<div class="card">
<div class="card-header">
<h3>Einführungstext im Tooltipp</h3>
</div>
<div class="card-body">
<label>Tooltipp-Text: (HTML erlaubt)</label>
<textarea name="introtext" id="input" class="form-control" style="width:35em;" rows="10" required="required">
<?=stripslashes($strIntroText) ?>
</textarea>
</div>
</div>
<br>
<input type="hidden" name="csrf" value="<?=$_SESSION['csrf_token']?>">
<input type="submit" class="btn btn-primary" value="Konfiguration ändern">
</form>
<br><br><br>
</div>
</div> <!-- row -->
</div>
</body>
</html>

View File

@ -0,0 +1,62 @@
<?php
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$dbFilename="../db/locations.db";
require("../config.php");
if($_POST['csrf'] !== $_SESSION['csrf_token']) {
die("Ungültiger Token");
}
$boolActive = (isset($_POST['active'])) ? "1" : "0";
$boolRating = (isset($_POST['rating'])) ? "1" : "0";
$boolComment = (isset($_POST['comment'])) ? "1" : "0";
$boolUpload = (isset($_POST['fileupload'])) ? "1" : "0";
$boolUserinfo = (isset($_POST['userinfo'])) ? "1" : "0";
$boolDefect = (isset($_POST['defect'])) ? "1" : "0";
$strUploaddir = $_POST['uploaddir'];
$strStadt = $_POST['district'];
$strTitle = $_POST['title'];
$fileGeojson =$_POST['geojson'];
$numInfoLat = $_POST['lat'];
$numInfoLng = $_POST['lng'];
$numZoom = $_POST['zoom'];
$strLogo = $_POST['logo'];
$contactEmail= $_POST['contactEmail'];
$strImpressum= $_POST['impressum'];
$strUrl = $_POST['url'];
$strUrlBez = $_POST['urlBez'];
$strIntroText= $_POST['introtext'];
$strImpressum=addslashes($strImpressum);
$strIntroText=addslashes($strIntroText);
$db->query("UPDATE config SET value= '$strUploaddir' WHERE key='uploaddir'");
$db->query("UPDATE config SET value= '$fileGeojson' WHERE key='fileGeojson'");
$db->query("UPDATE config SET value= '$strStadt' WHERE key='stadt'");
$db->query("UPDATE config SET value= '$strTitle' WHERE key='title'");
$db->query("UPDATE config SET value= '$numInfoLat' WHERE key='InfoLat'");
$db->query("UPDATE config SET value= '$numInfoLng' WHERE key='InfoLng'");
$db->query("UPDATE config SET value= '$numZoom' WHERE key='zoom'");
$db->query("UPDATE config SET value= '$strLogo' WHERE key='logo'");
$db->query("UPDATE config SET value= '$contactEmail' WHERE key='contactEmail'");
$db->query("UPDATE config SET value= '$strImpressum' WHERE key='impressum'");
$db->query("UPDATE config SET value= '$strUrl' WHERE key='url'");
$db->query("UPDATE config SET value= '$strUrlBez' WHERE key='UrlBez'");
$db->query("UPDATE config SET value= '$strIntroText' WHERE key='IntroText'");
$db->query("UPDATE config SET value= '$boolActive' WHERE key='boolActive'");
$db->query("UPDATE config SET value= '$boolRating' WHERE key='boolRating'");
$db->query("UPDATE config SET value= '$boolComment' WHERE key='boolComment'");
$db->query("UPDATE config SET value= '$boolUserinfo' WHERE key='boolUserinfo'");
$db->query("UPDATE config SET value= '$boolDefect' WHERE key='boolDefect'");
$db->query("UPDATE config SET value= '$boolUpload' WHERE key='boolUpload'");
header("Location: configuration.php");

90
admin/create_database.php Normal file
View File

@ -0,0 +1,90 @@
<?php
date_default_timezone_set('UTC');
$db = new SQLite3($dbFilename);
$db->exec("CREATE TABLE IF NOT EXISTS location(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username text NOT NULL DEFAULT '',
age text NOT NULL DEFAULT '',
transport text NOT NULL DEFAULT '',
description text NOT NULL DEFAULT '',
defect number,
topic number,
lng number,
lat number,
thumb_ups INTEGER DEFAULT 0,
thumb_downs INTEGER DEFAULT 0,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)");
$db->exec("CREATE TABLE IF NOT EXISTS files(
id INTEGER PRIMARY KEY AUTOINCREMENT,
loc_id INTEGER,
filename TEXT,
filetype TEXT,
filesize INTEGER
)");
$db->exec("CREATE TABLE IF NOT EXISTS comment(
id INTEGER PRIMARY KEY AUTOINCREMENT,
loc_id INTEGER,
username TEXT,
comment TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)");
$db->exec("CREATE TABLE IF NOT EXISTS user(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT,
passwordhash TEXT,
lastlogin TEXT DEFAULT CURRENT_TIMESTAMP,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)");
$db->exec("CREATE TABLE IF NOT EXISTS address(
id INTEGER PRIMARY KEY AUTOINCREMENT,
loc_id INTEGER,
parking TEXT,
road TEXT,
house_number TEXT,
industrial TEXT,
neighbourhood TEXT,
hamlet TEXT,
suburb TEXT,
postcode TEXT,
city TEXT,
county TEXT,
country TEXT
)");
$db->exec("CREATE TABLE IF NOT EXISTS 'config' ('key' TEXT PRIMARY KEY NOT NULL DEFAULT NULL, 'value' TEXT DEFAULT NULL);
INSERT INTO 'config' ('key','value') VALUES ('boolActive','1');
INSERT INTO 'config' ('key','value') VALUES ('boolRating','1');
INSERT INTO 'config' ('key','value') VALUES ('boolComment','1');
INSERT INTO 'config' ('key','value') VALUES ('boolUpload','1');
INSERT INTO 'config' ('key','value') VALUES ('boolUserinfo','0');
INSERT INTO 'config' ('key','value') VALUES ('boolDefect','1');
INSERT INTO 'config' ('key','value') VALUES ('uploaddir','/var/www/html/images/');
INSERT INTO 'config' ('key','value') VALUES ('title','Testversion Hamm');
INSERT INTO 'config' ('key','value') VALUES ('fileGeojson','geojson/hamm.geojson');
INSERT INTO 'config' ('key','value') VALUES ('InfoLat','51.66');
INSERT INTO 'config' ('key','value') VALUES ('InfoLng','7.825');
INSERT INTO 'config' ('key','value') VALUES ('zoom','12');
INSERT INTO 'config' ('key','value') VALUES ('logo','css/logo.png');
INSERT INTO 'config' ('key','value') VALUES ('contactEmail','info@radwege-hamm.de');
INSERT INTO 'config' ('key','value') VALUES ('impressum','Walter Hupfeld
Bankerheide 2
59065 Hamm');
INSERT INTO 'config' ('key','value') VALUES ('url','https://www.radwege-hamm.de');
INSERT INTO 'config' ('key','value') VALUES ('UrlBez','Homepage Radwege Hamm');
INSERT INTO 'config' ('key','value') VALUES ('IntroText','Hier können Sie uns Hinweise auf Verbesserungen der Verkehrsinfrastruktur in der Stadt Mülheim an der Ruhr vorschlagen.
Klicken Sie dazu auf entsprechenden Ort auf der Karte und geben Sie im Dialog ihre Anmerkungen ein.
Den Marker können sie solange auf die richtige Stelle verschieben, bis die Eingabe abgeschlossen ist.
Vielen Dank für Ihre Unterstützung.');
INSERT INTO 'config' ('key','value') VALUES ('stadt','Hamm');
");

61
admin/dump.php Normal file
View File

@ -0,0 +1,61 @@
<?php
/** *****************************
* Ideenmelder
* Autor: Walter Hupfeld, Hamm
* E-Mail: info@hupfeld-software.de
* Version: 1.0
* Datum: 18.05.2021
******************************** */
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$dbFilename="../db/locations.db";
require ("../config.php");
// Set headers to make the browser download the results as a csv file
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=dump.csv");
header("Pragma: no-cache");
header("Expires: 0");
// Query
$strSQL="SELECT l.id as lid,l.*,adr.*
FROM location l LEFT JOIN address adr ON l.id=adr.loc_id ORDER BY created_at ASC";
$query = $db->query($strSQL);
// Fetch the first row
$row = $query->fetchArray(SQLITE3_ASSOC);
// If no results are found, echo a message and stop
if ($row == false){
echo "No results";
exit;
}
// Print the titles using the first line
print_titles($row);
// Iterate over the results and print each one in a line
while ($row != false) {
// Print the line
$line = implode( ";",array_values($row));
$line = html_entity_decode($line);
$line = str_replace(array("\r\n", "\r", "\n"), "<br />", $line);
echo $line . "\n";
// Fetch the next line
$row = $query->fetchArray(SQLITE3_ASSOC);
}
// Prints the column names
function print_titles($row){
echo implode(";",array_keys($row)) . "\n";
}
?>

105
admin/export.php Normal file
View File

@ -0,0 +1,105 @@
<?php
/** *****************************
* Ideenmelder
* Autor: Walter Hupfeld, Hamm
* E-Mail: info@hupfeld-software.de
* Version: 1.0
* Datum: 18.05.2021
******************************** */
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$dbFilename="../db/locations.db";
require ("../config.php");
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/bootstrap.min.css" />
<link href="../css/font-awesome.min.css" rel="stylesheet">
<script src="../js/jquery.min.js"></script>
<title>Konfigruation</title>
<style>
.leftlabel { width: 10em;}
input[type="text"] { width: 18em;}
input.wide {width: 24em;}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Administration <?= $strTitle ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbars" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="index.php">Liste <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="configuration.php">Konfiguration </a>
</li>
<li class="nav-item">
<a class="nav-link" href="geocoding.php">Addressen ermitteln </a>
</li>
<li class="nav-item active">
<a class="nav-link" href="export.php">Export </a>
</li>
<li class="nav-item">
<a class="nav-link" href="password.php">Passwort ändern </a>
</li>
</ul>
<div>
<ul class="navbar-nav mr-auto right">
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout (<?=$strLoginName?>)</a>
</li>
</ul>
</div>
</nav>
<!-- Ende Navbar -->
<div class="container" style="margin-top:5em;">
<h1>Export</h1>
<div class="row">
<div class="col-md-7 col-lg-7">
<br>
<div class="card">
<div class="card-header">
<h3>CSV Exportieren</h3>
</div>
<div class="card-body">
<ul>
<li> <a href="print_html.php">HTML-Druckansicht</a></li>
<li> <a href="dump.php">CSV-Datei</a></li>
<li> <a href="shapefile.php">Shape-File (ZIP)</a></li>
</ul>
</div>
</div>
<br>
</div>
</div>
</div>
</body>
</html>

94
admin/geocoding.php Normal file
View File

@ -0,0 +1,94 @@
<?php
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$dbFilename="../db/locations.db";
require ("../config.php");
require ("../lib/geocoding.php");
$boolRefresh = (isset($_GET['refresh']) & $_GET['refresh']==1);
$strTable="";
if ($boolRefresh) {
cleanAddresses($db);
$strTable=fillAddressTable($db,20);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/bootstrap.min.css" />
<link href="../css/font-awesome.min.css" rel="stylesheet">
<script src="../js/jquery.min.js"></script>
<title>Konfigruation</title>
<style>
.leftlabel { width: 10em;}
input[type="text"] { width: 18em;}
input.wide {width: 24em;}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Administration <?= $strTitle ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbars" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="index.php">Liste <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="configuration.php">Konfiguration </a>
</li>
<li class="nav-item active">
<a class="nav-link" href="geocoding.php">Addressen ermitteln </a>
</li>
<li class="nav-item">
<a class="nav-link" href="export.php">Export </a>
</li>
<li class="nav-item">
<a class="nav-link" href="password.php">Passwort ändern </a>
</li>
</ul>
<div>
<ul class="navbar-nav mr-auto right">
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout (<?=$strLoginName?>)</a>
</li>
</ul>
</div>
</nav>
<!-- Ende Navbar -->
<div class="container" style="margin-top:5em;">
<h1>Adressen ermitteln</h1>
<p>Bei der Eingabe der Daten werden auch die zugehörigen Adressen ermittelt. Sollte das nicht funktionieren,
können mit dieser Funktion die Adressdaten nachträglich erfasst werden. Die Erfassung der Adressen erleichtert
die Auswertung der Daten, sie werden nur im Backend angezeigt.</p>
<p><strong>Achtung:</strong> Es werden aufgrund der Beschränkungen des Dienstes
jeweils nur 20 Datensätze ermittelt. Ggf. muss die Seite mehrmals aufgerufen werden.</p>
<p>Geduld - der Aufruf der Funktion beansprucht etwas Zeit.</p>
<div class="row">
<div class="col-5-md">
<ul class="list-group">
<li class="list-group-item">
<a href="<?=$_SERVER['PHP_SELF']?>?refresh=1">Adressen jetzt ermitteln</a></li>
</ul>
<br>
</div>
</div>
<?= $strTable ?>
</div>
</body>
</html>

332
admin/index.php Normal file
View File

@ -0,0 +1,332 @@
<?php
/** *****************************
* Ideenmelder
* Autor: Walter Hupfeld, Hamm
* E-Mail: info@hupfeld-software.de
* Version: 1.0
* Datum: 18.05.2021
******************************** */
session_start();
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$dbFilename = "../db/locations.db";
include("../config.php");
$boolShowmap=false;
if (isset($_GET['delid'])) {
if($_GET['csrf'] !== $_SESSION['csrf_token']) {
die("Ungültiger Token");
}
$numDelete = (int)$_GET['delid'];
$stmt = $db->prepare("DELETE FROM location WHERE id = :id");
$stmt->bindValue(":id",$numDelete);
$stmt->execute();
$stmt = $db->prepare("DELETE FROM comment WHERE loc_id= :loc_id");
$stmt->bindValue(":loc_id",$numDelete);
$stmt->execute();
$stmt = $db->prepare("SELECT * FROM files where loc_id = :loc_id");
$stmt->bindValue(":loc_id", $numDelete, SQLITE3_TEXT);
$result = $stmt->execute();
if ($row = $result->fetchArray()) {
$strFilename = $row['filename'];
$strFilename = $uploaddir . $strFilename;
unset($strFilename);
}
$stmt = $db->prepare("DELETE FROM files WHERE loc_id= :loc_id");
$stmt->bindValue(":loc_id",$numDelete);
$stmt->execute();
}
if (isset($_GET['delcid'])) {
if($_GET['csrf'] !== $_SESSION['csrf_token']) {
die("Ungültiger Token");
}
$numDelete=(int)$_GET['delcid'];
$stmt = $db->prepare("DELETE FROM comment WHERE id= :id");
$stmt->bindValue(":id",$numDelete);
$stmt->execute();
}
if (isset($_GET['delfid'])) {
if($_GET['csrf'] !== $_SESSION['csrf_token']) {
die("Ungültiger Token");
}
$numDelete=(int)$_GET['delfid'];
$stmt = $db->prepare("SELECT * FROM files where id = :id");
$stmt->bindValue(":id", $numDelete, SQLITE3_TEXT);
$result = $stmt->execute();
if ($row=$result->fetchArray()) {
$strFilename = $row['filename'];
$strFilename = $uploaddir . $strFilename;
unset($strFilename);
}
$stmt = $db->prepare("DELETE FROM files WHERE id= :id");
$stmt->bindValue(":id",$numDelete);
$stmt->execute();
}
if (isset($_GET['showmap'])) {
$numShowmap=(int)$_GET['showmap'];
$boolShowmap=$numShowmap==1;
}
$arrTopic = array (
1 => "Fußverkehr",
2 => "Radverkehr",
3 => "Bus und Bahn",
4 => "Pkw-Verkehr",
5 => "Lkw-Verkehr"
);
$arrIcon = array (
1 => "<i class='fa fa-male'></i>",
2 => "<i class='fa fa-bicycle'></i>",
3 => "<i class='fa fa-train'></i>",
4 => "<i class='fa fa-car'></i>",
5 => "<i class='fa fa-truck'></i>"
);
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/bootstrap.min.css" />
<link rel="stylesheet" href="../css/font-awesome.min.css">
<link rel="stylesheet" href="../css/lightbox.css" />
<link rel="stylesheet" href="../css/leaflet.css" />
<link rel="stylesheet" href="../css/leaflet.awesome-markers.css" />
<script src="../js/jquery.min.js"></script>
<script src="../js/leaflet.js"></script>
<script src="../js/leaflet.awesome-markers.js"></script>
<script src="../js/lightbox.min.js"></script>
<title>Eintragsliste</title>
<style>
.tdmap { height:350px; width:300px;}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Administration <?= $strTitle ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbars" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="index.php">Liste <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="configuration.php">Konfiguration </a>
</li>
<li class="nav-item">
<a class="nav-link" href="geocoding.php">Addressen ermitteln </a>
</li>
<li class="nav-item">
<a class="nav-link" href="export.php">Export </a>
</li>
<li class="nav-item">
<a class="nav-link" href="password.php">Passwort ändern </a>
</li>
</ul>
<div>
<ul class="navbar-nav mr-auto right">
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout (<?=$strLoginName?>)</a>
</li>
</ul>
</div>
</nav>
<!-- Ende Navbar -->
<div class="container-fluid" style="margin-top:5em;">
<table class="table table-bordered table-striped">
<thead>
<tr><th>id</th><th>Username</th>
<?= ($boolUserinfo) ? "<th>Alter</th><th>Transport</th>" : "" ?>
<th>Topic</th>
<th>Beschreibung</th>
<th><i class="fa fa-thumbs-up"></i></th><th><i class="fa fa-thumbs-down"></i></th>
<th>Kommentare</th>
<th>Adresse</th>
<th>Mangel</th>
<th>Bild</th>
<th>lat/lng</th>
<th>Datum</th>
<th>Aktion</th></tr>
</thead>
<tbody>
<?php
$strScript="";
//$strSQL="SELECT * FROM location ORDER BY created_at DESC";
$strSQL="SELECT l.id as lid,l.*,adr.* FROM location l LEFT JOIN address adr ON l.id=adr.loc_id ORDER BY created_at ASC";
$result = $db->query($strSQL);
while ($row = $result->fetchArray()) {
$id = $row['lid'];
echo "<tr>";
echo "<td>".$id."</td>";
echo "<td>". stripslashes($row['username']) ."</td>";
echo ($boolUserinfo) ? "<td>".$row['age']."</td><td>".$row['transport']."</td>" : "";
echo "<td>".$arrIcon[$row['topic']]." ".$arrTopic[$row['topic']]."</td>";
echo "<td id='desc_".$id."'>" . nl2br(stripslashes($row['description'])) . "</td>";
echo "<td>".$row['thumb_ups']."</td>";
echo "<td>".$row['thumb_downs']."</td>";
echo "<td>";
$strSQL = "SELECT id,username,comment,created_at FROM comment WHERE loc_id=".$id;
$comments = $db->query($strSQL);
while ($comment = $comments->fetchArray()) {
echo "<div class='comment'>";
echo "<em>".$comment['username']." schrieb am ";
$numDatum = strtotime($comment['created_at']);
$strDatum = date("d.m.Y",$numDatum);
echo $strDatum."</em><br>";
echo nl2br(stripslashes($comment['comment']));
echo "<a class='left' href='".$_SERVER['PHP_SELF']."?delcid=".$comment['id']."&csrf=".$_SESSION['csrf_token']."'><i class='fa fa-trash'></i></a>";
echo "</div>";
}
echo "</td>";
echo "<td>".$row['road']." ".$row['house_number']."<br>"
.$row['neighbourhood']." "
.$row['hamlet']." "
.$row['suburb']."</td>";
$strDefect = (isset($row['defect']) && $row['defect']>0) ? $arrDefect[$row['defect']] : "";
echo "<td id='defect_".$id."' value='".$row['defect']."'>".$strDefect."</td>\n";
echo "<td id='img_".$id."'>";
$strSQL = "SELECT id,filename FROM files WHERE loc_id=".$id;
$files=$db->query($strSQL);
if ($file=$files->fetchArray()) {
echo "<a href='../images/".$file['filename']."' data-lightbox='radweg".$id."'>";
echo "<img src='../images/".$file['filename']."' style='width:150px'></a>";
echo "<a href='".$_SERVER['PHP_SELF']."?delfid=".$file['id']."&csrf=".$_SESSION['csrf_token']."'><i class='fa fa-trash'></i></a>";
}
echo "</td>\n";
// Karte einblenden
if ($boolShowmap) {
echo "<td><div class='tdmap' id='map_".$id."'></div></td>\n";
}
else {
echo "<td>".round($row['lat'],5)." ".round($row['lng'],5)."</td>";
}
echo "<td>".$row['created_at']."</td>";
echo "<td><a class='del' href='".$_SERVER['PHP_SELF']."?delid=".$id."&csrf=".$_SESSION['csrf_token']."'><i class='fa fa-trash'></i></a>&nbsp;";
echo "<a class='edit_defect' href='#' id='edit_".$id."' value='".$id."'><i class='fa fa-pencil'></i></a>";
echo "</td>";
echo "</tr>\n";
if ($boolShowmap) {
$strScript.="var mymap_".$id." = L.map(map_".$id.").setView([".$row['lat'].", ".$row['lng']."], 16);\n";
$strScript.="L.tileLayer(url, {maxZoom: 18,minZoom:12,attribution: attribution,id: 'mapbox/streets-v11',tileSize: 512,zoomOffset: -1}).addTo(mymap_".$id.")\n";
$strScript.="L.marker([".$row['lat'].", ".$row['lng']."], { icon: infoMarker } ).addTo(mymap_".$id.")\n\n";
}
}
?>
</tbody>
</table>
<a class="btn btn-primary" href="../index.php?ref=1">zurück</a>
</div>
<?php include("../lib/dialog_edit_location.php"); ?>
<script>
$( document ).ready(function() {
var url = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var attribution = 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>';
var infoMarker = L.AwesomeMarkers.icon({icon: 'info', prefix: 'fa', markerColor: 'orange'});
$(".edit_defect").on("click", function(e){
e.preventDefault();
$('#dialog_defect').hide();
$('#dialog_defect').css({'top':e.pageY-90,'left':e.pageX-520});
id = $(this).attr("value");
descr = $("#desc_"+id).html();
descr = descr.replace(/(<|&lt;)br\s*\/*(>|&gt;)/g,' ');
$("#description").html(descr);
defect_id=$("#defect_"+id).attr("value");
$("#defect select").val(defect_id);
$("#loc_id").val(id);
$('#dialog_defect').show();
return false;
})
$(".del").click(function () {
result=confirm("Wirklich löschen?");
return result===true;
})
$("#editobjectform").submit(function(event){
event.preventDefault();
//grab all form data
var formData = new FormData($(this)[0]);
$.ajax({
type: "POST",
url: "../ajax/ajax_update.php",
enctype: 'multipart/form-data',
data: formData, //$("#newobjectform").serialize(), // serializes the form's elements.
processData: false,
contentType: false,
cache: false,
success: function(data)
{
$("#dialog_defect").hide();
console.log(data);
newdata=JSON.parse(data);
console.log(newdata);
id=newdata.id;
$("#desc_"+id).html(newdata.description);
$("#defect_"+id).html(newdata.defect);
if (newdata.filename>"") {
img="<img src='../images/"+newdata.filename+"' style='width:150px;'>";
$("#img_"+id).html(img);
}
//$("#btnSubmit").prop("disabled", false);
event.preventDefault();
},
error: function(data)
{
alert('Fehler: Konnte keine Daten senden!');
}
});
return false;
});
$('#close').click(function(e){
$('#dialog_defect').hide();
});
<?= $strScript ?>
});
</script>
</body>
</html>

108
admin/login.php Normal file
View File

@ -0,0 +1,108 @@
<?php
/** *****************************
* Ideenmelder
* Autor: Walter Hupfeld, Hamm
* E-Mail: info@hupfeld-software.de
* Version: 1.0
* Datum: 18.05.2021
******************************** */
$dbFilename = "../db/locations.db";
require_once("../config.php");
$boolLogin=true;
if (isset($_POST['login']) && isset($_POST['password'])) {
$strUser = trim($_POST['login']);
$strPassword = trim($_POST['password']);
$strSQL = "SELECT username,passwordhash FROM user WHERE username='$strUser'";
$result = $db->query($strSQL);
if ($row=$result->fetchArray()) {
if (password_verify($strPassword,$row['passwordhash'])) {
session_start();
$_SESSION['user']=$strUser;
$_SESSION['csrf_token'] = uniqid('', true);
header ("Location: index.php");
} else {
$boolLogin=false;
}
}
else {
$boolLogin=false;
}
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<link rel="stylesheet" href="../css/bootstrap.min.css" />
<link rel="stylesheet" href="../css/style.css" />
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#"><?= $strTitle ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbars" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="../index.php?ref=1">Karte</a>
</li>
</ul>
</div>
</nav>
<!-- Ende Navbar -->
<div class="container main" style="margin-top:8em;">
<div class="row">
<div class="col-md-5">
<?php if (!$boolLogin): ?>
<div class="alert alert-danger">
<strong>Fehler!</strong> Login nicht erfolgreich!
</div> <br>
<?php endif; ?>
<div class="card">
<div class="card-header">
<h2>Login</h2>
</div>
<div class="card-body">
<form id="login" action="<?=$_SERVER['PHP_SELF']?>" method="post">
<div class="form-group">
<label for="username">Login</label>
<input type="text" name="login" class="form-control" id="username" placeholder="Nutzername" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" id="password" placeholder="Passwort" required>
</div>
<button type="submit" class="btn btn-primary">Absenden</button>
</form>
</div>
</div>
</div>
</div>
<div style="margin-top:5em;">
<a class="btn btn-primary text-white" href="../index.php?ref=1">zurück</a>
</div>
</div>
</body>
</html>

5
admin/logout.php Normal file
View File

@ -0,0 +1,5 @@
<?php
session_start();
session_destroy();
header ("Location: ../index.php");

156
admin/password.php Normal file
View File

@ -0,0 +1,156 @@
<?php
/** *****************************
* Ideenmelder
* Autor: Walter Hupfeld, Hamm
* E-Mail: info@hupfeld-software.de
* Version: 1.0
* Datum: 18.05.2021
******************************** */
session_start();
$dbFilename="../db/locations.db";
require ("../config.php");
$strLoginName=(isset($_SESSION['user'])) ? $_SESSION['user'] : "" ;
$boolLogin = (!empty($strLoginName));
if (!$boolLogin) {
header("Location: login.php");
}
$boolError=false;
if (isset($_POST['password1']) && isset($_POST['password2']) && isset($_POST['username']) ) {
if($_POST['csrf'] !== $_SESSION['csrf_token']) {
die("Ungültiger Token");
}
$strPassword=trim($_POST['password1']);
$strPassword2=trim($_POST['password2']);
if ($strPassword==$strPassword2) {
$strUsername=$_POST['username'];
$strPasswordHash = password_hash($strPassword,PASSWORD_BCRYPT);
$strSQL="UPDATE user SET passwordhash = :passwordhash WHERE username=:username";
$stmt = $db->prepare($strSQL);
$stmt->bindValue(':username', $strUsername);
$stmt->bindValue(':passwordhash', $strPasswordHash);
$stmt->execute();
if ($stmt) {
header("Location: index.php");
} else {
$boolError=true;
}
} else $boolError=true;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/bootstrap.min.css" />
<link href="../css/font-awesome.min.css" rel="stylesheet">
<script src="../js/jquery.min.js"></script>
<title>Passwort ändern</title>
<style>
.leftlabel { width: 13em;}
input[type="text"] { width: 16em;}
input.wide {width: 24em;}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">Administration <?= $strTitle ?></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbars" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="index.php">Liste <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="configuration.php">Konfiguration </a>
</li>
<li class="nav-item">
<a class="nav-link" href="export.php">Export </a>
</li>
<li class="nav-item active">
<a class="nav-link" href="password.php">Passwort ändern </a>
</li>
</ul>
<div>
<ul class="navbar-nav mr-auto right">
<li class="nav-item">
<a class="nav-link" href="logout.php">Logout (<?=$strLoginName?>)</a>
</li>
</ul>
</div>
</nav>
<!-- Ende Navbar -->
<div class="container" style="margin-top:5em;">
<h2>Passwort ändern</h2>
<div class="row">
<div class="col-md-7 col-lg-7">
<br>
<?php if ($boolError): ?>
<div class="alert alert-danger">
<strong>Fehler!</strong> Password konnte nicht geändert werden!
</div> <br>
<div class="card">
<?php endif; ?>
<div class="card-header">
<h3>Dateneingabe</h3>
</div>
<form id="login" action="<?=$_SERVER['PHP_SELF']?>" method="post">
<div class="card-body">
<label class="leftlabel">Nutzername: </label>
<input type="text" name="username" id="username" value="<?=$strLoginName?>" readonly ><br>
<label class="leftlabel">Passwort (mind. 8 Zeichen): </label>
<input type="password" name="password1" id="password1" value="" minlength="8" required><br>
<label class="leftlabel">Passwort (Wdh.): </label>
<input type="password" name="password2" id="password2" value="" minlength="8" required><br><br>
<label class="leftlabel">&nbsp;</label>
<input type="hidden" name="csrf" value="<?=$_SESSION['csrf_token']?>">
<button type="submit" class="btn btn-primary">Passwort ändern</button>
</div>
</form>
</div>
<br>
</div>
</div>
</div>
<script>
$('#myform').submit(function(e){
password1 = $("#password1").val();
password2 = $("#password2").val();
if (password1.length==0 && password2.legthn==0) {
return true;
}
if (password1==password2) {
return true;
} else {
alert("Passwörter nicht gleich");
return false;
e.preventDefault();
}
});
</script>
</body>
</html>

141