Initial commit

This commit is contained in:
nils 2020-11-25 14:53:18 +01:00 committed by Nils Otterpohl
commit 809fa2d1a4
62 changed files with 9311 additions and 0 deletions

119
LICENSE Normal file
View File

@ -0,0 +1,119 @@
Creative Commons Legal Code
CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES
NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE
AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE
OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS
LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION
OR WORKS PROVIDED HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer exclusive
Copyright and Related Rights (defined below) upon the creator and subsequent
owner(s) (each and all, an "owner") of an original work of authorship and/or
a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later claims
of infringement build upon, modify, incorporate in other works, reuse and
redistribute as freely as possible in any form whatsoever and for any purposes,
including without limitation commercial purposes. These owners may contribute
to the Commons to promote the ideal of a free culture and the further production
of creative, cultural and scientific works, or to gain reputation or greater
distribution for their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with
a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or
her Copyright and Related Rights in the Work and the meaning and intended
legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be protected
by copyright and related or neighboring rights ("Copyright and Related Rights").
Copyright and Related Rights include, but are not limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work, subject
to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal protection
of databases, and under any national implementation thereof, including any
amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time extensions),
(iii) in any current or future medium and for any number of copies, and (iv)
for any purpose whatsoever, including without limitation commercial, advertising
or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the
benefit of each member of the public at large and to the detriment of Affirmer's
heirs and successors, fully intending that such Waiver shall not be subject
to revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account Affirmer's
express Statement of Purpose. In addition, to the extent the Waiver is so
judged Affirmer hereby grants to each affected person a royalty-free, non
transferable, non sublicensable, non exclusive, irrevocable and unconditional
license to exercise Affirmer's Copyright and Related Rights in the Work (i)
in all territories worldwide, (ii) for the maximum duration provided by applicable
law or treaty (including future time extensions), (iii) in any current or
future medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional purposes
(the "License"). The License shall be deemed effective as of the date CC0
was applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder of
the License, and in such case Affirmer hereby affirms that he or she will
not (i) exercise any of his or her remaining Copyright and Related Rights
in the Work or (ii) assert any associated claims and causes of action with
respect to the Work, in either case contrary to Affirmer's express Statement
of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered,
licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or other
defects, accuracy, or the present or absence of errors, whether or not discoverable,
all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims
responsibility for obtaining any necessary consents, permissions or other
rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a party
to this document and has no duty or obligation with respect to this CC0 or
use of the Work.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# App

34
bin/errors.php Normal file
View File

@ -0,0 +1,34 @@
<?php #bin/errors.php
//Check if errors were reported
if (count($err["out"])>0)
{
$etpl = tplExtrSection(tplLoadFile(TPLERRORS), "###ERRORS###");
$eshow = true;
$elog = true;
$edet = true;
//0: none, 1: report in output, 2: report to file (log/errors.txt), 4: just count, 8: only if admin, 16: only if param
//Sums are possible (e.g. 3 means reporting both to file and output
if ((DEBUGLVL > 16) && !isset($input["debug"])) {$eshow = false; $elog = false;}
if ((DEBUGLVL % 16 > 8) && !access(USRADMIN)) {$eshow = false; $elog = false;}
if (DEBUGLVL % 8 >= 4) $edet = false;
if (DEBUGLVL % 4 < 2) $elog = false;
if (DEBUGLVL % 2 < 1) $eshow = false;
if ($edet)
{
$eent = tplExtrSection($etpl, "###ERRORENTRY###");
foreach ($err["out"] as $emsg)
{
$output["error"].= tplReplMarker($eent, "###ERRORMSG###", $emsg);
###### TODO: ##### log into file ##### if ($elog) ...
}
}
else
{
$output["error"] = count($err["out"])." errors occured!";
##### TODO: ##### log into file #### if ($elog) ...
}
if ($eshow) $output["error"] = tplReplSection($etpl, "###ERRORENTRY###", $output["error"]); else $output["error"] = "";
}
?>

5
bin/exit.php Normal file
View File

@ -0,0 +1,5 @@
<?php #bin/exit.php
$mysqli->close();
?>

70
bin/init.php Normal file
View File

@ -0,0 +1,70 @@
<?php #bin/init.php
//Include libraries (excl. hidden [.file])
$files["lib"] = scandir("lib");
foreach ($files["lib"] as $val)
if (substr($val,0,1)!= ".") include "lib/".$val;
//Import configuration files (excl. hidden [.file])
$files["var"] = scandir("var");
foreach ($files["var"] as $val)
if (substr($val,0,1)!= ".") include "var/".$val;
error_reporting(ERRORLVL);
ini_set("display_errors", 1);
lgnSecSessionStart(); // Unsere selbstgemachte sichere Funktion um eine PHP-Sitzung zu starten
lgnRegenerateToken(); // Erzeugt neuen Token
//Clean input
function cleanInput($array) {
$ret = array();
foreach ($array as $key => $value) {
$ret[$key] = is_array($value) ? cleanInput($value) : (is_string($value) ? SS($value) : SI($value));
}
return $ret;
}
$input = cleanInput($_REQUEST);
//Check login attempt
if (isset($input["login"],$input["pass"],$input["submit"]) && $input["secToken"]==$_SESSION["secTokenVerify"])
{
//Login attempt
if (!lgnLogin($mysqli, $input["login"], $input["pass"]))
{
addError("Login Failed: ", $mysqli->error);
}
}
//Init main variables
//array $page = (string main, string sub, array css = [strings], array js = [strings])
//array $output = (string stat, string navi, string main)
//array $temp = (EMPTY) - can be used for temporary variables
$page = array
(
"main" => "",
"sub" => ""
);
$output = array
(
"stat" => tplLoadFile(FRAMETPL), //Load Mainframe
"main" => "",
"navi" => "",
"error" => "",
"css" => array(),
"js" => array(),
"showlogin" => "in"
);
addStyle(FRAMECSS, FRAMECSS!="");
addJScript(FRAMEJS, FRAMEJS!="");
$temp = array();
$user = array(
"address.plural" => 1
);
if (isset($input["userMod"]) && $input["userMod"]=="Ausloggen")
{
lgnLogout();
}
?>

21
bin/navi.php Normal file
View File

@ -0,0 +1,21 @@
<?php #bin/navi.php
$output["navi"] = tplExtrSection(tplLoadFile("res/nav.html"), "###NAVLINE###");
$nent = tplExtrSection($output["navi"], "###NAVENTRY###");
$nsep = tplExtrSection($output["navi"], "###NAVSEPERATOR###");
$nout = "";
$x = false;
foreach ($pages as $key => $val)
{
if ($x) {
$nout.= $nsep;
}
$fill = pgsCreatePage($val["name"], "?main=".$val["ID"], $val["ID"]==$page["main"] ? " current" : "");
$nout.= tplReplMarkerArray($nent, $fill);
$x = true;
}
$output["navi"] = $nout;
?>

63
bin/print.php Normal file
View File

@ -0,0 +1,63 @@
<?php #bin/print.php
//array $page = (int main, string sub, array css = [strings], array js = [strings])
//Include CSS
$tplcss = tplExtrSection($output["stat"], "###CSS###");
$css = "";
$x = false;
foreach ($output["css"] as $val)
{
$css.= tplReplMarker($tplcss, "###CSSFILE###", $val."?id=".lgnGenSalt()).($x ? "\n" : "");
$x = true;
}
$output["stat"] = tplReplSection($output["stat"], "###CSS###", $css);
//Include Javascript
$tpljs = tplExtrSection($output["stat"], "###JS###");
$js = "";
$x= false;
foreach ($output["js"] as $val)
{
$js.= tplReplMarker($tpljs, "###JSFILE###", $val).($x ? "\n" : "");
$x = true;
}
$output["stat"] = tplReplSection($output["stat"], "###JS###", $js);
//Additional
$output["stat"] = tplReplMarker($output["stat"], "###NAV###", $output["navi"]);
$output["stat"] = tplReplMarker($output["stat"], "###MAIN###", $output["main"]);
$output["stat"] = tplReplMarker($output["stat"], "###PAGETYPE###", $page["main"]=="" ? "frontpage" : "content");
$output["stat"] = tplReplMarker($output["stat"], "###TITLE###", TITLE);
$output["stat"] = tplReplMarker($output["stat"], "###LINKSTART###", "");
$output["stat"] = tplReplMarker($output["stat"], "###PAGEMAIN###", $page["main"]);
$url = parse_url("https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
$output["stat"] = tplReplMarker($output["stat"], "###PAGEURL###", "https://".$url["host"].$url["path"]);
$output["stat"] = tplReplMarker($output["stat"], "###PAGEDOMAIN###", str_replace("www.", "", $url["host"]));
$output["stat"] = tplReplMarker($output["stat"], "###ERRORS###", $output["error"]);
//Print login/logout forms
if ($output["showlogin"]=="in") {
//$tpllgn = tplExtrSection($output["stat"], "###LOGIN###");
$output["stat"] = tplReplSection($output["stat"], "###LOGOFF###", "");
$gets = "";
foreach ($_GET as $key => $value) {
$gets.= ($gets=="" ? "?" : "&").$key."=".$value;
}
$output["stat"] = tplReplMarker($output["stat"], "###PAGEGET###", $gets);
} elseif ($output["showlogin"]=="off") {
//$tpllgn = tplExtrSection($output["stat"], "###LOGOFF###");
$output["stat"] = tplReplSection($output["stat"], "###LOGIN###", "");
}
foreach ($lang as $key => $value) {
$output["stat"] = tplReplMarker($output["stat"], $key, $value[$user["address.plural"]]);
}
$output["stat"] = tplReplMarker($output["stat"], "###SECTOKEN###", $_SESSION["secTokenUse"]);
//Print page
echo $output["stat"];
?>

858
database_structure.sql Normal file
View File

@ -0,0 +1,858 @@
-- phpMyAdmin SQL Dump
-- version 5.0.4
-- https://www.phpmyadmin.net/
--
-- Host: localhost
-- Generation Time: Nov 25, 2020 at 05:27 PM
-- Server version: 10.5.8-MariaDB
-- PHP Version: 7.4.12
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `Feuerwehr_Kameradenverwaltung`
--
-- --------------------------------------------------------
--
-- Table structure for table `Abteilungen`
--
CREATE TABLE `Abteilungen` (
`ID` int(11) NOT NULL,
`Kürzel` varchar(3) NOT NULL,
`Name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":29}';
-- --------------------------------------------------------
--
-- Table structure for table `Ausbildungen`
--
CREATE TABLE `Ausbildungen` (
`ID` int(11) NOT NULL,
`Kürzel` varchar(3) DEFAULT NULL,
`Name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":24}';
-- --------------------------------------------------------
--
-- Table structure for table `Berechtigungen`
--
CREATE TABLE `Berechtigungen` (
`ID` int(11) NOT NULL,
`Name` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `Dienstbuch`
--
CREATE TABLE `Dienstbuch` (
`ID` int(11) NOT NULL,
`Abteilung` int(11) NOT NULL,
`Anfang` datetime NOT NULL,
`Ende` datetime NOT NULL,
`Leiter` int(11) NOT NULL,
`Ort` varchar(50) NOT NULL,
`Thema` varchar(50) NOT NULL,
`Bemerkungen` varchar(250) NOT NULL,
`Kategorie` int(11) NOT NULL,
`TM2Thema` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":11}';
-- --------------------------------------------------------
--
-- Table structure for table `Dienstpläne`
--
CREATE TABLE `Dienstpläne` (
`ID` int(11) NOT NULL,
`Abteilung` int(11) NOT NULL,
`Jahr` smallint(4) NOT NULL,
`Name` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":11,"target":"concat(Jahr, '' '', Name)"}';
-- --------------------------------------------------------
--
-- Table structure for table `Einsatzarten`
--
CREATE TABLE `Einsatzarten` (
`ID` int(11) NOT NULL COMMENT '{}',
`Einsatzkategorie` int(11) NOT NULL COMMENT '{"target":"name"}',
`Name` varchar(255) NOT NULL,
`Stichworte` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":31,"order":{"column":"Name","sorting":"asc"}}';
-- --------------------------------------------------------
--
-- Table structure for table `Einsatzkategorien`
--
CREATE TABLE `Einsatzkategorien` (
`ID` int(11) NOT NULL COMMENT '{}',
`Name` varchar(255) NOT NULL,
`Farbe` varchar(255) NOT NULL DEFAULT '#000000'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":30,"order":{"column":"Name","sorting":"asc"}}';
-- --------------------------------------------------------
--
-- Table structure for table `Einsätze`
--
CREATE TABLE `Einsätze` (
`ID` int(11) NOT NULL,
`Alarmierungszeit` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`Einsatzende` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`Adresse` varchar(255) NOT NULL,
`Einsatzart` int(11) DEFAULT NULL,
`Zusammenfassung` varchar(255) NOT NULL,
`Einsatzleiter` varchar(255) NOT NULL DEFAULT '',
`Überprüft` bit(1) NOT NULL DEFAULT b'0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":13,"order":{"column":"Alarmierungszeit","sorting":"desc"},"target":"concat(Adresse, date_format(Alarmierungszeit, '' (%d.%m.%Y)''))"}';
-- --------------------------------------------------------
--
-- Table structure for table `Kommandofunktionen`
--
CREATE TABLE `Kommandofunktionen` (
`ID` int(11) NOT NULL,
`Kürzel` varchar(3) NOT NULL,
`Name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":20}';
-- --------------------------------------------------------
--
-- Table structure for table `link_Abteilungen_Personal`
--
CREATE TABLE `link_Abteilungen_Personal` (
`Abteilungen` int(11) NOT NULL COMMENT '{"dynitem":true}',
`Personal` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `link_Ausbildungen_Personal`
--
CREATE TABLE `link_Ausbildungen_Personal` (
`Ausbildungen` int(11) NOT NULL COMMENT '{"dynitem":true}',
`Personal` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"show":false}';
-- --------------------------------------------------------
--
-- Table structure for table `link_Berechtigungen_Personalgruppen`
--
CREATE TABLE `link_Berechtigungen_Personalgruppen` (
`Berechtigungen` int(11) NOT NULL,
`Personalgruppen` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `link_Personal_Personalgruppen`
--
CREATE TABLE `link_Personal_Personalgruppen` (
`Personal` int(11) NOT NULL,
`Personalgruppen` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `Personal`
--
CREATE TABLE `Personal` (
`ID` int(11) NOT NULL,
`OFnr` tinyint(2) UNSIGNED DEFAULT 56 COMMENT '{"group":"nummer","group_title":"P-Nr.","postfix":"-"}',
`Pnr` smallint(3) UNSIGNED ZEROFILL DEFAULT NULL COMMENT '{"group":"nummer"}',
`Login` varchar(50) NOT NULL,
`Nachnamen` varchar(255) NOT NULL COMMENT '{"group":"Name","group_title":"Namen","group_sep":", "}',
`Vornamen` varchar(255) NOT NULL COMMENT '{"group":"Name"}',
`Bildadresse` varchar(255) DEFAULT NULL COMMENT '{"input":"file"}',
`Pool` int(11) DEFAULT NULL COMMENT '{"dynitem":true}',
`Kommandofkt` int(11) DEFAULT NULL COMMENT '{"dynitem":true}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":10,"order":{"column":"Name","sorting":"asc"},"target":"concat(left(Vornamen, 1), ''. '', Nachnamen)"}';
-- --------------------------------------------------------
--
-- Table structure for table `Personalgruppen`
--
CREATE TABLE `Personalgruppen` (
`ID` int(11) NOT NULL,
`Kürzel` varchar(3) NOT NULL,
`Name` varchar(255) DEFAULT NULL,
`Abteilung` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `Pools`
--
CREATE TABLE `Pools` (
`ID` int(11) NOT NULL,
`Name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":21}';
-- --------------------------------------------------------
--
-- Table structure for table `print_elements`
--
CREATE TABLE `print_elements` (
`ID` int(11) NOT NULL COMMENT '{}',
`key_layout_ID` int(11) NOT NULL COMMENT '{"title":"Drucklayout","dynitem":true,"target":"name"}',
`cond` varchar(255) NOT NULL COMMENT '{"title":"Bedingung"}',
`content` varchar(255) NOT NULL DEFAULT '#%field%#' COMMENT '{"title":"Inhalt"}',
`posl` decimal(10,0) NOT NULL COMMENT '{"title":"Pos. von links [mm]"}',
`post` decimal(10,0) NOT NULL COMMENT '{"title":"Pos. von oben [mm]"}',
`dimw` decimal(10,0) NOT NULL COMMENT '{"title":"Breite [mm]"}',
`dimh` decimal(10,0) NOT NULL COMMENT '{"title":"Höhe [mm]"}',
`type` varchar(255) NOT NULL DEFAULT 'text' COMMENT '{"title":"Art"}',
`params` varchar(255) NOT NULL DEFAULT '{}' COMMENT '{"title":"Parameter"}',
`ord` int(11) NOT NULL COMMENT '{"title":"Reihenfolge"}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":99,"show":true,"title":"Druckelemente"}';
-- --------------------------------------------------------
--
-- Table structure for table `print_layouts`
--
CREATE TABLE `print_layouts` (
`ID` int(11) NOT NULL COMMENT '{}',
`name` varchar(255) NOT NULL COMMENT '{"title":"Bezeichnung"}',
`page` varchar(255) NOT NULL COMMENT '{"title":"Seite","options":"pages"}',
`width` int(10) UNSIGNED NOT NULL COMMENT '{"title":"Breite"}',
`height` int(10) UNSIGNED NOT NULL COMMENT '{"title":"Höhe"}',
`options` varchar(255) NOT NULL COMMENT '{"title":"Optionen"}',
`prio` tinyint(1) NOT NULL DEFAULT 0 COMMENT '{"title":"Bevorzugt"}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":98,"show":true,"title":"Drucklayouts"}';
-- --------------------------------------------------------
--
-- Table structure for table `sys_failedlogins`
--
CREATE TABLE `sys_failedlogins` (
`ID` int(11) NOT NULL COMMENT '{"title":"ID", "target":"login"}',
`time` int(11) NOT NULL COMMENT '{"title":"Zeitstempel"}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"title":"FailedLogin"}';
-- --------------------------------------------------------
--
-- Table structure for table `sys_iservhashes`
--
CREATE TABLE `sys_iservhashes` (
`ID` int(11) NOT NULL,
`Hash` char(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `sys_pass`
--
CREATE TABLE `sys_pass` (
`ID` int(11) NOT NULL COMMENT '{"title":"ID", "target":"login"}',
`iterations` int(11) NOT NULL COMMENT '{"title":"Iterations"}',
`salt` char(32) NOT NULL COMMENT '{"title":"Salt"}',
`hash` char(64) NOT NULL COMMENT '{"title":"Hash"}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{}';
-- --------------------------------------------------------
--
-- Table structure for table `sys_uaccess`
--
CREATE TABLE `sys_uaccess` (
`ID` int(11) NOT NULL,
`key_sys_user_ID` int(11) NOT NULL COMMENT '{"title":"User", "target":"login"}',
`page` varchar(255) NOT NULL COMMENT '{"title":"Seite","options":"pages"}',
`access` tinyint(2) NOT NULL DEFAULT 0 COMMENT '{"title":"Seitenzugriff"}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{}';
-- --------------------------------------------------------
--
-- Table structure for table `sys_user`
--
CREATE TABLE `sys_user` (
`ID` int(11) NOT NULL COMMENT '{"title":"ID"}',
`login` varchar(32) NOT NULL COMMENT '{"title":"Login"}',
`email` varchar(64) NOT NULL COMMENT '{"title":"eMail"}',
`key_personal_ID` int(11) DEFAULT NULL COMMENT '{"title":"Nachnamen","target":"nachnamen"}',
`access` tinyint(2) NOT NULL DEFAULT 0 COMMENT '{"title":"Hauptzugriff"}'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{}';
-- --------------------------------------------------------
--
-- Table structure for table `Teilnahmestatus`
--
CREATE TABLE `Teilnahmestatus` (
`ID` int(11) NOT NULL,
`Name` varchar(10) NOT NULL,
`Loswert` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `Terminarten`
--
CREATE TABLE `Terminarten` (
`ID` int(11) NOT NULL COMMENT '{}',
`Name` varchar(255) NOT NULL,
`Präfix` varchar(50) NOT NULL DEFAULT '',
`Farbe` varchar(7) NOT NULL DEFAULT '#000000',
`Beschreibung` text NOT NULL,
`Verwaltungsrecht` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":31,"order":{"column":"Name","sorting":"asc"}}';
-- --------------------------------------------------------
--
-- Table structure for table `Termine`
--
CREATE TABLE `Termine` (
`ID` int(11) NOT NULL COMMENT '{}',
`Beginn` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`Ende` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`Thema` varchar(255) CHARACTER SET utf8 NOT NULL,
`Ort` varchar(255) CHARACTER SET utf8 NOT NULL,
`Verantwortliche` varchar(255) CHARACTER SET utf8 NOT NULL,
`Dienstplan` int(11) DEFAULT NULL,
`Terminart` int(11) DEFAULT NULL,
`Platzvergabe` int(11) DEFAULT NULL,
`Ausgelost` tinyint(1) NOT NULL DEFAULT 0,
`Personalgruppe` int(11) DEFAULT NULL,
`Hash` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '{"input":"hash"}',
`TeilnahmeGeändert` tinyint(1) DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{"sort":12,"order":{"column":"Beginn","sorting":"desc"},"target":"concat(date_format(Beginn, ''%d.%m.''), '' '', Thema)"}';
-- --------------------------------------------------------
--
-- Table structure for table `Terminplatzvergabe`
--
CREATE TABLE `Terminplatzvergabe` (
`ID` int(11) NOT NULL,
`Name` varchar(25) NOT NULL,
`Tage` int(11) NOT NULL DEFAULT 0,
`LoescheGruppeTage` int(11) DEFAULT NULL,
`MaxTeilnehmer` int(11) NOT NULL DEFAULT 0,
`MinZF` int(11) NOT NULL DEFAULT 0,
`MinGF` int(11) NOT NULL DEFAULT 0,
`MinF` int(11) NOT NULL DEFAULT 0,
`MinKFohneF` int(11) NOT NULL DEFAULT 0,
`MinKF` int(11) NOT NULL DEFAULT 0,
`MinAGTohneF` int(11) NOT NULL DEFAULT 0,
`MinAGT` int(11) NOT NULL DEFAULT 0,
`MinTHohneF` int(11) NOT NULL DEFAULT 0,
`MinTH` int(11) NOT NULL DEFAULT 0,
`MinNon` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- --------------------------------------------------------
--
-- Table structure for table `Terminteilnahmen`
--
CREATE TABLE `Terminteilnahmen` (
`Termin` int(11) NOT NULL,
`Personal` int(11) NOT NULL,
`Status` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `Abteilungen`
--
ALTER TABLE `Abteilungen`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `Ausbildungen`
--
ALTER TABLE `Ausbildungen`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `Berechtigungen`
--
ALTER TABLE `Berechtigungen`
ADD PRIMARY KEY (`ID`),
ADD UNIQUE KEY `Berechtigungen_UN` (`Name`);
--
-- Indexes for table `Dienstbuch`
--
ALTER TABLE `Dienstbuch`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_dienstplaene_abteilung` (`Abteilung`);
--
-- Indexes for table `Dienstpläne`
--
ALTER TABLE `Dienstpläne`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_dienstplaene_abteilung` (`Abteilung`);
--
-- Indexes for table `Einsatzarten`
--
ALTER TABLE `Einsatzarten`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_einsatzarten_einsatzkategorie` (`Einsatzkategorie`);
--
-- Indexes for table `Einsatzkategorien`
--
ALTER TABLE `Einsatzkategorien`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `Einsätze`
--
ALTER TABLE `Einsätze`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_einsatzberichte_einsatzart` (`Einsatzart`);
--
-- Indexes for table `Kommandofunktionen`
--
ALTER TABLE `Kommandofunktionen`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `link_Abteilungen_Personal`
--
ALTER TABLE `link_Abteilungen_Personal`
ADD PRIMARY KEY (`Abteilungen`,`Personal`),
ADD KEY `fk_link_Abteilungen_Personal_2` (`Personal`);
--
-- Indexes for table `link_Ausbildungen_Personal`
--
ALTER TABLE `link_Ausbildungen_Personal`
ADD PRIMARY KEY (`Ausbildungen`,`Personal`),
ADD KEY `fk_link_personal_ausbildungen_1` (`Personal`),
ADD KEY `fk_link_personal_ausbildungen_2` (`Ausbildungen`);
--
-- Indexes for table `link_Berechtigungen_Personalgruppen`
--
ALTER TABLE `link_Berechtigungen_Personalgruppen`
ADD PRIMARY KEY (`Berechtigungen`,`Personalgruppen`),
ADD KEY `fk_link_Berechtigungen_Personalgruppen_2` (`Personalgruppen`);
--
-- Indexes for table `link_Personal_Personalgruppen`
--
ALTER TABLE `link_Personal_Personalgruppen`
ADD PRIMARY KEY (`Personal`,`Personalgruppen`),
ADD KEY `fk_link_Personal_Personalgruppen_2` (`Personalgruppen`);
--
-- Indexes for table `Personal`
--
ALTER TABLE `Personal`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_personal_1` (`Kommandofkt`),
ADD KEY `fk_personal_2` (`Pool`);
--
-- Indexes for table `Personalgruppen`
--
ALTER TABLE `Personalgruppen`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_Personalgruppen_1` (`Abteilung`);
--
-- Indexes for table `Pools`
--
ALTER TABLE `Pools`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `print_elements`
--
ALTER TABLE `print_elements`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_print_elements_1` (`key_layout_ID`);
--
-- Indexes for table `print_layouts`
--
ALTER TABLE `print_layouts`
ADD PRIMARY KEY (`ID`),
ADD KEY `page` (`page`);
--
-- Indexes for table `sys_failedlogins`
--
ALTER TABLE `sys_failedlogins`
ADD PRIMARY KEY (`ID`,`time`);
--
-- Indexes for table `sys_iservhashes`
--
ALTER TABLE `sys_iservhashes`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `sys_pass`
--
ALTER TABLE `sys_pass`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `sys_uaccess`
--
ALTER TABLE `sys_uaccess`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_sys_access_1` (`key_sys_user_ID`);
--
-- Indexes for table `sys_user`
--
ALTER TABLE `sys_user`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_sys_users_1` (`key_personal_ID`);
--
-- Indexes for table `Teilnahmestatus`
--
ALTER TABLE `Teilnahmestatus`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `Terminarten`
--
ALTER TABLE `Terminarten`
ADD PRIMARY KEY (`ID`),
ADD KEY `Terminarten_FK` (`Verwaltungsrecht`);
--
-- Indexes for table `Termine`
--
ALTER TABLE `Termine`
ADD PRIMARY KEY (`ID`),
ADD KEY `fk_Termine_Dienstplan` (`Dienstplan`),
ADD KEY `fk_Termine_Terminart` (`Terminart`),
ADD KEY `Termine_FK` (`Platzvergabe`),
ADD KEY `fk_Termine_Personalgruppe` (`Personalgruppe`);
--
-- Indexes for table `Terminplatzvergabe`
--
ALTER TABLE `Terminplatzvergabe`
ADD PRIMARY KEY (`ID`);
--
-- Indexes for table `Terminteilnahmen`
--
ALTER TABLE `Terminteilnahmen`
ADD PRIMARY KEY (`Termin`,`Personal`),
ADD KEY `fk_terminteilnahmen_1` (`Personal`),
ADD KEY `fk_terminteilnahmen_3` (`Status`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `Abteilungen`
--
ALTER TABLE `Abteilungen`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Ausbildungen`
--
ALTER TABLE `Ausbildungen`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Berechtigungen`
--
ALTER TABLE `Berechtigungen`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Dienstbuch`
--
ALTER TABLE `Dienstbuch`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Dienstpläne`
--
ALTER TABLE `Dienstpläne`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Einsatzarten`
--
ALTER TABLE `Einsatzarten`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{}';
--
-- AUTO_INCREMENT for table `Einsatzkategorien`
--
ALTER TABLE `Einsatzkategorien`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{}';
--
-- AUTO_INCREMENT for table `Einsätze`
--
ALTER TABLE `Einsätze`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Kommandofunktionen`
--
ALTER TABLE `Kommandofunktionen`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Personal`
--
ALTER TABLE `Personal`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Personalgruppen`
--
ALTER TABLE `Personalgruppen`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Pools`
--
ALTER TABLE `Pools`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `print_elements`
--
ALTER TABLE `print_elements`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{}';
--
-- AUTO_INCREMENT for table `print_layouts`
--
ALTER TABLE `print_layouts`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{}';
--
-- AUTO_INCREMENT for table `sys_uaccess`
--
ALTER TABLE `sys_uaccess`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `sys_user`
--
ALTER TABLE `sys_user`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{"title":"ID"}';
--
-- AUTO_INCREMENT for table `Teilnahmestatus`
--
ALTER TABLE `Teilnahmestatus`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT for table `Terminarten`
--
ALTER TABLE `Terminarten`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{}';
--
-- AUTO_INCREMENT for table `Termine`
--
ALTER TABLE `Termine`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '{}';
--
-- AUTO_INCREMENT for table `Terminplatzvergabe`
--
ALTER TABLE `Terminplatzvergabe`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `Dienstpläne`
--
ALTER TABLE `Dienstpläne`
ADD CONSTRAINT `fk_dienstplaene_abteilung` FOREIGN KEY (`Abteilung`) REFERENCES `Abteilungen` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `Einsatzarten`
--
ALTER TABLE `Einsatzarten`
ADD CONSTRAINT `fk_einsatzarten_einsatzkategorie` FOREIGN KEY (`Einsatzkategorie`) REFERENCES `Einsatzkategorien` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `Einsätze`
--
ALTER TABLE `Einsätze`
ADD CONSTRAINT `fk_einsatzberichte_einsatzart` FOREIGN KEY (`Einsatzart`) REFERENCES `Einsatzarten` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `link_Abteilungen_Personal`
--
ALTER TABLE `link_Abteilungen_Personal`
ADD CONSTRAINT `fk_link_Abteilungen_Personal_1` FOREIGN KEY (`Abteilungen`) REFERENCES `Abteilungen` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_link_Abteilungen_Personal_2` FOREIGN KEY (`Personal`) REFERENCES `Personal` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `link_Ausbildungen_Personal`
--
ALTER TABLE `link_Ausbildungen_Personal`
ADD CONSTRAINT `fk_link_personal_ausbildungen_1` FOREIGN KEY (`Personal`) REFERENCES `Personal` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_link_personal_ausbildungen_2` FOREIGN KEY (`Ausbildungen`) REFERENCES `Ausbildungen` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `link_Berechtigungen_Personalgruppen`
--
ALTER TABLE `link_Berechtigungen_Personalgruppen`
ADD CONSTRAINT `fk_link_Berechtigungen_Personalgruppen_1` FOREIGN KEY (`Berechtigungen`) REFERENCES `Berechtigungen` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_link_Berechtigungen_Personalgruppen_2` FOREIGN KEY (`Personalgruppen`) REFERENCES `Personalgruppen` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `link_Personal_Personalgruppen`
--
ALTER TABLE `link_Personal_Personalgruppen`
ADD CONSTRAINT `fk_link_Personal_Personalgruppen_1` FOREIGN KEY (`Personal`) REFERENCES `Personal` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_link_Personal_Personalgruppen_2` FOREIGN KEY (`Personalgruppen`) REFERENCES `Personalgruppen` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `Personal`
--
ALTER TABLE `Personal`
ADD CONSTRAINT `fk_personal_1` FOREIGN KEY (`Kommandofkt`) REFERENCES `Kommandofunktionen` (`ID`) ON UPDATE CASCADE,
ADD CONSTRAINT `fk_personal_2` FOREIGN KEY (`Pool`) REFERENCES `Pools` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `Personalgruppen`
--
ALTER TABLE `Personalgruppen`
ADD CONSTRAINT `fk_Personalgruppen_1` FOREIGN KEY (`Abteilung`) REFERENCES `Abteilungen` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `print_elements`
--
ALTER TABLE `print_elements`
ADD CONSTRAINT `fk_print_elements_1` FOREIGN KEY (`key_layout_ID`) REFERENCES `print_layouts` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `sys_failedlogins`
--
ALTER TABLE `sys_failedlogins`
ADD CONSTRAINT `fk_sys_failedlogins_1` FOREIGN KEY (`ID`) REFERENCES `sys_user` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `sys_iservhashes`
--
ALTER TABLE `sys_iservhashes`
ADD CONSTRAINT `fk_sys_iservhashes_1` FOREIGN KEY (`ID`) REFERENCES `Personal` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `sys_pass`
--
ALTER TABLE `sys_pass`
ADD CONSTRAINT `fk_sys_pass_1` FOREIGN KEY (`ID`) REFERENCES `sys_user` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `sys_uaccess`
--
ALTER TABLE `sys_uaccess`
ADD CONSTRAINT `fk_sys_access_1` FOREIGN KEY (`key_sys_user_ID`) REFERENCES `sys_user` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Constraints for table `sys_user`
--
ALTER TABLE `sys_user`
ADD CONSTRAINT `fk_sys_users_1` FOREIGN KEY (`key_personal_ID`) REFERENCES `Personal` (`ID`) ON DELETE SET NULL ON UPDATE CASCADE;
--
-- Constraints for table `Terminarten`
--
ALTER TABLE `Terminarten`
ADD CONSTRAINT `Terminarten_FK` FOREIGN KEY (`Verwaltungsrecht`) REFERENCES `Berechtigungen` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `Termine`
--
ALTER TABLE `Termine`
ADD CONSTRAINT `Termine_FK` FOREIGN KEY (`Platzvergabe`) REFERENCES `Terminplatzvergabe` (`ID`) ON UPDATE CASCADE,
ADD CONSTRAINT `fk_Termine_Dienstplan` FOREIGN KEY (`Dienstplan`) REFERENCES `Dienstpläne` (`ID`) ON UPDATE CASCADE,
ADD CONSTRAINT `fk_Termine_Personalgruppe` FOREIGN KEY (`Personalgruppe`) REFERENCES `Personalgruppen` (`ID`) ON DELETE SET NULL ON UPDATE CASCADE,
ADD CONSTRAINT `fk_Termine_Terminart` FOREIGN KEY (`Terminart`) REFERENCES `Terminarten` (`ID`) ON UPDATE CASCADE;
--
-- Constraints for table `Terminteilnahmen`
--
ALTER TABLE `Terminteilnahmen`
ADD CONSTRAINT `fk_terminteilnahmen_1` FOREIGN KEY (`Personal`) REFERENCES `Personal` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `fk_terminteilnahmen_2` FOREIGN KEY (`Termin`) REFERENCES `Termine` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

35
index.php Normal file
View File

@ -0,0 +1,35 @@
<?php #/index.php
require_once "bin/init.php";
//Parse page(s)
//array $page = (int main, string sub, array css = [strings], array js = [strings])
//array $output = (string stat, string main, string navi)
if ($userID = lgnCheckLogin($mysqli)) {
$pages = pgsLoadPages($mysqli, $userID);
if (sizeof($pages)==0) {
$output["main"] = "No pages to show";
} else {
$page["main"] = (isset($input["main"]) && isset($pages[$input["main"]])) ? $input["main"] : key($pages);
$page["sub"] = isset($input["sub"]) ? $input["sub"] : "main";
include "bin/navi.php";
$files["pgs"] = pgsIncPage($pages[$page["main"]]["path"]);
if (file_exists("pgs/".$pages[$page["main"]]["path"]."/lib.php")) {
include "pgs/".$pages[$page["main"]]["path"]."/lib.php";
}
if ($files["pgs"]) {
include $files["pgs"];
}
$output["showlogin"] = "off";
}
}
//Include error-handling, print page and quit
include "bin/errors.php"; //Parse error reporting
include "bin/print.php"; //Print page
include "bin/exit.php"; //Conclusions
?>

77
lib/00_main.php Normal file
View File

@ -0,0 +1,77 @@
<?php #lib/main.php
/********************************************************************************
* Content: Most important functions *
* Author: Nils Otterpohl *
* Last modification: 24.06.2019 *
* Version: alpha (incomplete, tested, commented) *
********************************************************************************/
#### INCOMPLETE! TBD: ##############
# Mehr Datums- und Zeitformate #
####################################
function SS($param)
{ //Prevents injections from strings
global $mysqli;
return $mysqli->escape_string($param);
}
function SI($param)
{ //Prevents injections from integers
return intval($param);
}
function myDate($time = 0)
{ //Formats timestamp to standard date format
if ($time==0) $time = time();
return date(FORMATDATE, $time);
}
function myTime($time = 0)
{ //Formats timestamp to standard time format
if ($time==0) $time = time();
return date(FORMATTIME, $time);
}
function myDateTime($time = 0)
{ //Formats timestamp to standard date and time format
return myDate($time)." ".myTime($time);
}
function fmtTime($format, $time = 0)
{ //Formats timestamp to a preset value
global $times;
return (isset($times[$format]) ? date($times[$format], $time) : myDateTime);
}
function addError($ident, $add)
{ //Lists an error
global $err;
if (isset($err[$ident])) $err["out"][] = $err[$ident].$add;
else $err["out"][] = $err["unknown"].$ident.$add;
}
function addLibrary($lib, $notify=true)
{ //Includes a php-library
global $err;
if (!(substr($lib,0,4)=="lib/")) $lib = "lib/".$lib;
if (!(substr($lib,-4,4)==".php")) $lib.= ".php";
if (file_exists($lib)) include_once($lib);
elseif ($notify) addError("noLib", $lib);
}
function addStyle($css, $notify=true)
{ //adds a stylesheet to $output-array
global $output, $err;
if (file_exists($css) && ! in_array($css,$output["css"])) $output["css"][] = $css;
elseif ($notify) addError("noCss", $css);
}
function addJscript($js, $notify=true)
{ //adds a javascript to $output-array
global $output, $err;
if (file_exists($js) && ! in_array($js,$output["js"])) $output["js"][] = $js;
elseif ($notify) addError("noJs", $js);
}
?>

254
lib/10_login.php Normal file
View File

@ -0,0 +1,254 @@
<?php #lib/10_login.php
/********************************************************************************
* Content: Login related functions *
* Author: Nils Otterpohl *
* Last modification: 24.06.2019 *
* Version: alpha (incomplete, tested, commented) *
********************************************************************************/
function lgnGenHash($password, $salt, $iterations, $length = 32, $algo = "sha256") {
return hash_pbkdf2($algo, $password, $salt, $iterations, $length*2);
}
function lgnGenSalt($length = 16) {
return bin2hex(random_bytes($length));
}
function lgnTransformPassword($password = "") {
$salt = lgnGenSalt();
if ($password=="")
$password = lgnGenSalt(8);
return array(
"password" => $password,
"iterations" => DESIRED_ITERATIONS,
"salt" => $salt,
"hash" => lgnGenHash($password, $salt, DESIRED_ITERATIONS)
);
}
function lgnSecSessionStart() {
// Copied and adjusted after https://de.wikihow.com/Ein-sicheres-Login-Skript-mit-PHP-und-MySQL-erstellen
// Zwingt die Sessions nur Cookies zu benutzen.
if (ini_set("session.use_only_cookies", 1) === FALSE) {
exit();
}
// Holt Cookie-Parameter.
$cookieParams = session_get_cookie_params();
// Erstes true = Nur https Zugriff, Zweites true = Blockt JavaScript Zugriff
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], true, true);
$sessionName = "SessionOfHigherSecureness";
session_name($sessionName);
session_start(); // Startet die PHP-Sitzung
session_regenerate_id(); // Erneuert die Session, löscht die alte.
}
function lgnRegenerateToken() {
if (isset($_SESSION["secTokenUse"])) {
$_SESSION["secTokenVerify"] = $_SESSION["secTokenUse"];
} else {
$_SESSION["secTokenVerify"] = "";
}
$_SESSION["secTokenUse"] = lgnGenSalt(16);
}
function lgnLogin($mysqli, $login, $password) {
// Copied and adjusted after https://de.wikihow.com/Ein-sicheres-Login-Skript-mit-PHP-und-MySQL-erstellen
// and https://github.com/nextcloud/user_external/blob/master/lib/webdavauth.php
// Das Benutzen vorbereiteter Statements verhindert SQL-Injektion.
$login = strtolower($login);
$login = str_replace("@feuerwehr-bs.net", "", $login);
if ($stmt = $mysqli->prepare("SELECT p.ID, p.login FROM Personal p WHERE p.login = ? LIMIT 1")) {
$stmt->bind_param("s", $login); // Bind "$login" to parameter.
$stmt->execute(); // Führe die vorbereitete Anfrage aus.
$stmt->store_result();
// hole Variablen von result.
$stmt->bind_result($userID, $userLogin);
$stmt->fetch();
if ($stmt->num_rows == 1) {
$url= 'https://'.urlencode($userLogin).':'.urlencode($password).'@feuerwehr-bs.net/webdav';
$headers = get_headers($url);
if($headers === false) {
addError("loginFailed", 'ERROR: Not possible to connect to WebDAV Url: "https://feuerwehr-bs.net/webdav"');
return false;
}
$returnCode= substr($headers[0], 9, 3);
if(substr($returnCode, 0, 1) === '2') {
// Passwort ist korrekt!
// Hole den user-agent string des Benutzers.
$userBrowser = $_SERVER["HTTP_USER_AGENT"];
// XSS-Schutz, denn eventuell wird der Wert gedruckt
$userID = preg_replace("/[^0-9]+/", "", $userID);
$_SESSION["userID"] = $userID;
// XSS-Schutz, denn eventuell wird der Wert gedruckt
$userLogin = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $userLogin);
$_SESSION["userLogin"] = $userLogin;
// Generiere einen Hash aus dem Passwort mit zufälligem Salt und speichere ihn in der Datenbank
$hash = lgnGenHash($password, lgnGenSalt(), DESIRED_ITERATIONS);
$_SESSION["loginString"] = lgnGenHash($hash, $userBrowser, 10, 64, "sha512");
$mysqli->query("REPLACE INTO sys_iservhashes(ID, Hash) VALUES ('".$userID."', '".$hash."')");
// Login erfolgreich.
return true;
} else {
// Passwort ist nicht korrekt
addError("loginFailed", " Passwort nicht korrekt. Fehlercode (bitte an Nils senden): ".$returnCode);
}
} else {
addError("loginFailed", "Benutzername inkorrekt ".$login);
}
}
if ($mysqli->error!="") {
addError("mysql", $mysqli->error);
}
return false;
}
function lgnLogout() {
// Setze alle Session-Werte zurück
$_SESSION = array();
// hole Session-Parameter
$params = session_get_cookie_params();
// Lösche das aktuelle Cookie.
setcookie(
session_name(),
'',
time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]
);
// Vernichte die Session
session_destroy();
header('Location: index.php');
}
function lgnChangePass($mysqli, $userID, $passOld, $passNew, $passRepeat) {
$ret = false;
if ($passOld==$passNew) {
addError("passChangeFail", "Neues und altes Passwort sind nicht unterschiedlich?");
} else if (strlen($passNew)<12) {
addError("passChangeFail", "Passwort muss mindestens 12 Zeichen haben!");
} else if ($passNew!=$passRepeat) {
addError("passChangeFail", "Passwortwiederholung falsch!");
} else {
if ($stmt = $mysqli->prepare("SELECT iterations, salt, hash FROM users WHERE ID = ? LIMIT 1")) {
$stmt->bind_param("i", $_SESSION["userID"]);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($passIterations, $passSalt, $passHash);
$stmt->fetch();
if ($stmt->num_rows == 1) {
if (lgnGenHash($passOld, $passSalt, $passIterations)!=$passHash) {
addError("passChangeFail", "Altes Passwort inkorrekt!");
} else {
$newSalt = lgnGenSalt();
$newHash = lgnGenHash($passNew, $newSalt, DESIRED_ITERATIONS);
$mysqli->query("UPDATE users SET iterations='".DESIRED_ITERATIONS."', salt='".$newSalt."', hash='".$newHash."' "
."WHERE ID='".$_SESSION["userID"]."'");
$userBrowser = $_SERVER["HTTP_USER_AGENT"];
$_SESSION["loginString"] = lgnGenHash($newHash, $userBrowser, 10, 64, "sha512");
$ret = true;
}
}
} else {
addError("passChangeFailed", $mysqli->error);
}
}
return $ret;
}
function lgnCheckBrute($mysqli, $userID) {
// Copied and adjusted after https://de.wikihow.com/Ein-sicheres-Login-Skript-mit-PHP-und-MySQL-erstellen
// Hole den aktuellen Zeitstempel
// Alle Login-Versuche der letzten zwei Stunden werden gezählt.
if ($stmt = $mysqli->prepare("SELECT time FROM failedlogins WHERE ID = ? AND time > DATE_SUB(NOW(), INTERVAL 2 HOUR)")) {
$stmt->bind_param("i", $userID);
// Führe die vorbereitet Abfrage aus.
$stmt->execute();
$stmt->store_result();
// Wenn es mehr als 5 fehlgeschlagene Versuche gab
if ($stmt->num_rows > 5) {
return true;
}
}
return false;
}
function lgnCheckLogin($mysqli) {
// Überprüfe, ob alle Session-Variablen gesetzt sind
if (isset($_SESSION["userID"], $_SESSION["userLogin"], $_SESSION["loginString"])) {
$userID = $_SESSION["userID"];
$loginString = $_SESSION["loginString"];
$userLogin = $_SESSION["userLogin"];
// Hole den user-agent string des Benutzers.
$userBrowser = $_SERVER["HTTP_USER_AGENT"];
// Die UserID wird hier nochmal abgerufen, damit dem Rückgabewert der Funktion vertraut werden kann
if ($stmt = $mysqli->prepare("SELECT ID, Hash FROM sys_iservhashes WHERE ID = ? LIMIT 1")) {
$stmt->bind_param("i", $userID);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
// Wenn es den Benutzer gibt, hole die Variablen von result.
$stmt->bind_result($uID, $uHash);
$stmt->fetch();
if (lgnGenHash($uHash, $userBrowser, 10, 64, "sha512") == $loginString) {
// Eingeloggt!!!!
return $uID;
}
}
}
}
// Nicht eingeloggt
if ($mysqli->error!="") {
addError("mysql", $mysqli->error);
}
return false;
}
function lgnCheckRight($mysqli, $right, $userID = null) {
if ($right==null) {
return true;
}
if ($userID==null) {
$userID = lgnCheckLogin($mysqli);
}
$query = "SELECT b.name FROM Personal p "
."LEFT JOIN link_Personal_Personalgruppen lpp ON p.ID=lpp.Personal "
."LEFT JOIN link_Berechtigungen_Personalgruppen lbp ON lbp.Personalgruppen = lpp.Personalgruppen "
."LEFT JOIN Berechtigungen b ON b.ID = lbp.Berechtigungen "
."WHERE p.ID = ".$userID." and b.Name ";
if (is_array($right)) {
$query.= "IN ('".implode("', '", $right)."')";
} else {
$query.= "= '".$right."'";
}
if ($res = $mysqli->query($query)) {
if ($res->num_rows>0) {
return true;
}
}
return false;
}
?>

75
lib/20_template.php Normal file
View File

@ -0,0 +1,75 @@
<?php #lib/20_template.php
/********************************************************************************
* Content: Template-System *
* Author: Nils Otterpohl *
* Last modification: 21.07.2010 *
* Version: final (complete, tested, commented) *
********************************************************************************/
function tplLoadFile($tpl)
{ //returns a template
if (file_exists($tpl)) {
return file_get_contents($tpl);
} else if (file_exists($tpl.".html")) {
return file_get_contents($tpl.".html");
} else {
addError("noTpl", $tpl);
return "";
}
}
function tplCheckMarker(&$marker)
{ //ensures correctness of marker
while (!(substr($marker,0,3)=="###")) $marker = "#".$marker;
while (!(substr($marker,-3,3)=="###")) $marker = $marker."#";
}
function tplMakeSectionMarker($marker, $pos)
{ //creates START or END marker of section
$ret = "<!-- " . $marker . " " . $pos . " -->";
return $ret;
}
function tplExtrSection($tpl, $section)
{ //Extracts a section from a template
tplCheckMarker($section);
$start = tplMakeSectionMarker($section, "START");
$end = tplMakeSectionMarker($section, "END");
$start = strpos($tpl, $start)+strlen($start);
$end = strrpos($tpl, $end);
if (($start===false) || ($end===false) || ($end<=$start)) return "";
return substr($tpl, $start,$end-$start);
}
function tplReplSection($tpl, $section, $value)
{ //replaces a section in a template with a value
tplCheckMarker($section);
$start = tplMakeSectionMarker($section, "START");
$end = tplMakeSectionMarker($section, "END");
$start = strpos($tpl, $start);
$end = strrpos($tpl, $end)+strlen($end);
if (($start===false) || ($end===false) || ($end<=$start)) return $tpl;
$ret = ($start>0 ? substr($tpl, 0, $start) : "");
$ret.= $value;
if ($end<strlen($tpl)) $ret.= substr($tpl, $end);
return $ret;
}
function tplReplMarker($tpl, $marker, $value)
{ //replaces a marker in a template with a value
tplCheckMarker($marker);
return str_replace($marker, $value, $tpl);
}
function tplReplMarkerArray($tpl, $array)
{ //replaces all markers in a template with values from an array (index defines marker)
foreach ($array as $ind => $val)
{
tplCheckMarker($ind);
$tpl = str_replace($ind, $val, $tpl);
}
return $tpl;
}
?>

67
lib/30_pages.php Normal file
View File

@ -0,0 +1,67 @@
<?php #lib/30_pages.php
/********************************************************************************
* Content: Pages-Management *
* Author: Nils Otterpohl *
* Last modification: 24.06.2019 *
* Version: stable (complete, tested, uncommented) *
********************************************************************************/
function pgsCreatePage($label, $link, $class)
{
#Creates array with markers required for navigation
return array(
"###NAVLABEL###" => $label,
"###NAVHREF###" => $link,
"###NAVCLASS###" => $class
);
}
function pgsLoadPages($mysqli, $userID) {
/* userID unused for now, maybe will add page access control if neccessary */
$ret = array();
$dir = scandir("pgs");
foreach ($dir as $val) {
if ($val!="." && $val!="..") {
if (file_exists("pgs/".$val."/module.json")) {
$json = json_decode(file_get_contents("pgs/".$val."/module.json"), true);
if (lgnCheckRight($mysqli, $json["useRight"], $userID)) {
$key = $json["moduleName"];
$ret[$key]["ID"] = $json["moduleName"];
$ret[$key]["name"] = $json["title"];
$ret[$key]["path"] = $val;
$ret[$key]["tpl"] = pgsCreatePage($val, "", "");
}
}
}
}
return $ret;
}
function pgsIncPage($name)
{
#Checks if a mainpage exists, completes filename and returns valid page or default
$path = "pgs/".$name."/";
$possiblefiles = array("index.php", $name.".php");
foreach ($possiblefiles as $val)
{
if (file_exists($path.$val)) return $path.$val;
}
}
function pgsInclSub($name)
{ //
global $pages,$page;
$possibleexts = array("", ".php", ".htm", ".html", ".txt");
$file = "pgs/".$pages[$page["main"]]["path"]."/".$name;
foreach ($possibleexts as $val)
{
if (file_exists($file.$val)) return $file.$val;
}
addError("pgsInc", $name);
return false;
}
?>

4623
lib/40_PHPMailer.php Normal file

File diff suppressed because it is too large Load Diff

1347
lib/41_SMTP.php Normal file

File diff suppressed because it is too large Load Diff

39
lib/42_Exception.php Normal file
View File

@ -0,0 +1,39 @@
<?php
/**
* PHPMailer Exception class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2017 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer exception handler.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/
class Exception extends \Exception
{
/**
* Prettify error message output.
*
* @return string
*/
public function errorMessage()
{
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
}
}

192
lib/43_email.php Normal file
View File

@ -0,0 +1,192 @@
<?php #lib/main.php
/********************************************************************************
* Content: email related functions *
* Author: Nils Otterpohl *
********************************************************************************/
function emlSendEmail($to, $subject, $text) {
global $mail;
$mail->setFrom(MAILNOREPLY, "Webserver OF Innenstadt");
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $text;
$mail->addAddress($to);
$mail->send();
$mail->clearAddresses();
}
// string $email
// array $prenames
// array $surnames
// string $password
function emlSendInvitation($email, $invites, $password) {
global $mail;
$mail->setFrom(MAILNOREPLY, "Sophia und Nils Hochzeitswebsite");
$mail->addAddress($email);
$mail->isHTML(true);
$mail->Subject = "Einladung zur Hochzeit von Sophia und Nils";
$tpl = tplLoadFile("res/invitation.html");
$text = tplExtrSection($tpl, "###INVITATION###");
$to_tpl = tplExtrSection($text, "###TO###");
$to = "";
$count = 0;
foreach ($invites as $names) {
if ($names["companion"]==0) {
$count++;
$replace = array(
"###ADDRESSING###" => $names["addressing"],
"###PRENAMES###" => $names["prenames"],
"###SURNAMES###" => $names["surnames"],
"###NICKNAME###" => $names["nickname"]=="" ? $names["prenames"] : $names["nickname"]
);
$to.= tplReplMarkerArray($to_tpl, $replace);
}
}
$text = tplReplSection($text, "###TO###", $to);
$text = tplReplSection($text, "###INTRO###", $count>1 ? tplExtrSection($tpl, "###INTRO.MULTI###") : tplExtrSection($tpl, "###INTRO.SINGLE###"));
$text = tplReplSection($text, "###EXPLANATION###", $count>1 ? tplExtrSection($tpl, "###EXPLANATION.MULTI###") : tplExtrSection($tpl, "###EXPLANATION.SINGLE###"));
$text = tplReplSection($text, "###MULTIPLEASE###", $count>1 ? tplExtrSection($tpl, "###MULTIPLEASE###") : "");
$url = parse_url("https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
$text = tplReplMarker($text, "###PAGEURL###", "https://".$url["host"].$url["path"]);
$text = tplReplMarker($text, "###EMAIL###", $email);
$text = tplReplMarker($text, "###PASSWORD###", $password);
$mail->Body = $text;
$attachments = explode(";", tplExtrSection($tpl, "###ATTACHMENTS###"));
foreach ($attachments as $attachment) {
if ($attachment!="") {
$attributes = explode("|", $attachment);
if (count($attributes)>1 && $attributes[0]=="embedded") {
$mail->addEmbeddedImage($attributes[1].$attributes[2], $attributes[3], $attributes[2]);
} else {
$mail->addAttachment($attachment);
}
}
}
//$mail->addEmbeddedImage("res/Einladung.png", "cid_einladung", "Einladung.png");
$mail->send();
$mail->clearAddresses();
$mail->clearAttachments();
return true;
}
// mysql_con mysqli
// string subject
// string text
// int notificationLvl : {1: Neuer Thread, 2: Neue Nachricht}
// string neededRecipientRight
function emlSendNotification($mysqli, $sendUser, $subject, $text, $notificationLvl, $neededRecipientRight = null) {
global $mail;
$mail->setFrom(MAILNOREPLY, "Sophia und Nils Hochzeitswebsite");
$mail->isHTML(false);
$mail->Subject = $subject;
$to_tpl = tplExtrSection($text, "###TO###");
$qry = "SELECT DISTINCT u.email, u.groupID FROM users u "
.($neededRecipientRight!==null ? "LEFT JOIN rolerights rr ON rr.roleID=u.roleID LEFT JOIN rights r ON r.ID=rr.rightID " : "")
."WHERE u.ID!=".$sendUser." AND u.notifications>=".$notificationLvl." ".($neededRecipientRight!==null ? "AND r.name='".$neededRecipientRight."' " : "");
$res = $mysqli->query($qry);
while ($row = $res->fetch_assoc()) {
$nameres = $mysqli->query("SELECT prenames `###PRENAMES###`, surnames `###SURNAMES###`, addressing `###ADDRESSING###`, IFNULL(nickname, prenames) `###NICKNAME###` "
."FROM guests WHERE companion=0 AND groupID=".$row["groupID"]);
$to = "";
while ($namerow = $nameres->fetch_assoc()) {
$to.= tplReplMarkerArray($to_tpl, $namerow);
}
$mail->Body = tplReplSection($text, "###TO###", $to);
$mail->addAddress($row["email"]);
$mail->send();
$mail->clearAddresses();
}
}
// Sendet eine Mail an ALLE User (die nicht abgesagt haben)
// mysql_con mysqli
// int sendUser
// string from
// string subject
// string text
// string neededRecipientRight
function emlSendMassMail($mysqli, $sendUser, $from, $subject, $text, $neededRecipientRight = null) {
global $mail;
if (!$res = $mysqli->query("SELECT DISTINCT IFNULL(u.eMailFrom, u.email) email FROM users u WHERE u.ID=".$sendUser))
addError("Mysql", $mysqli->error);
$from_mail = $res->fetch_assoc()["email"];
$mail->setFrom($from_mail, $from);
$mail->isHTML(true);
$mail->Subject = $subject;
$to_tpl = tplExtrSection($text, "###TO###");
$qry = "SELECT DISTINCT u.email, u.groupID FROM guests g LEFT JOIN users u ON u.groupID=g.groupID "
.($neededRecipientRight!==null ? "LEFT JOIN rolerights rr ON rr.roleID=u.roleID LEFT JOIN rights r ON r.ID=rr.rightID " : "")
."WHERE u.ID!=".$sendUser." AND IFNULL(g.comes, 99)!=0 ".($neededRecipientRight!==null ? "AND r.name='".$neededRecipientRight."' " : "");
$res = $mysqli->query($qry);
while ($row = $res->fetch_assoc()) {
$tores = $mysqli->query("SELECT prenames `###PRENAMES###`, surnames `###SURNAMES###`, addressing `###ADDRESSING###`, IFNULL(nickname, prenames) `###NICKNAME###` "
."FROM guests WHERE companion=0 AND groupID=".$row["groupID"]);
$to = "";
while ($torow = $tores->fetch_assoc()) {
$to.= tplReplMarkerArray($to_tpl, $torow);
}
$mail->Body = tplReplSection($text, "###TO###", $to);
$mail->addAddress($row["email"]);
$mail->send();
$mail->clearAddresses();
}
}
// Sendet eine Mail an EINEN User
// mysql_con mysqli
// int targetUser
// string subject
// string text
function emlSendSingleMail($mysqli, $targetUser, $subject, $text) {
global $mail;
$ret = false;
$targetMail = null;
$groupID = null;
if ($stmt = $mysqli->prepare("SELECT email, groupID FROM users u WHERE u.ID = ?")) {
$stmt->bind_param("i", $targetUser);
$stmt->execute();
$stmt->bind_result($targetMail, $groupID);
$stmt->fetch();
$stmt->close();
} else {
addError("Mysql", $mysqli->error);
}
if ($targetMail!=null && $groupID!=null) {
$mail->setFrom(MAILNOREPLY, "Sophia und Nils Hochzeitswebsite");
$mail->isHTML(true);
$mail->Subject = $subject;
$to_tpl = tplExtrSection($text, "###TO###");
$tores = $mysqli->query("SELECT prenames `###PRENAMES###`, surnames `###SURNAMES###`, addressing `###ADDRESSING###`, IFNULL(nickname, prenames) `###NICKNAME###` "
."FROM guests WHERE companion=0 AND groupID=".$groupID);
$to = "";
while ($torow = $tores->fetch_assoc()) {
$to.= tplReplMarkerArray($to_tpl, $torow);
}
$mail->Body = tplReplSection($text, "###TO###", $to);
$mail->addAddress($targetMail);
$mail->send();
$mail->clearAddresses();
$ret = true;
}
return $ret;
}
?>

25
lib/50_content.php Normal file
View File

@ -0,0 +1,25 @@
<?php #lib/50_content.php
/********************************************************************************
* Content: Content-Management *
* Author: Nils Otterpohl *
* Last modification: 15.07.2019 *
********************************************************************************/
function cntCipherTextSym($text, $cipher)
{
$outText = "";
// Iterate through each character
for ($i=0;$i<strlen($text);) // Dont need to increment here
{
for ($j=0; $j<strlen($cipher) && $i<strlen($text); $j++, $i++)
{
$outText .= $text{$i} ^ $cipher{$j};
}
}
return $outText;
}
?>

362
pgs/dienste/index.php Normal file
View File

@ -0,0 +1,362 @@
<?php #pgs/dienste/index.php
$tpl = array(
"main" => tplExtrSection(tplLoadFile("pgs/dienste/main.html"), "DIENSTE"),
"show" => "",
"list" => ""
);
//die("Wartung");
addStyle("pgs/dienste/main.css");
// Anleitung zeigen
$tpl["show"] = tplExtrSection($tpl["main"], "###DIENSTE.SHOW###");
if ($userID = lgnCheckLogin($mysqli)) {
// Abteilungen und Gruppen abrufen
$res = $mysqli->query("SELECT l.Abteilungen, a.Name FROM link_Abteilungen_Personal l LEFT JOIN Abteilungen a ON a.ID=l.Abteilungen WHERE l.Personal='".$userID."'");
$abteilungen = array();
$abteilungenIDs = array();
while ($row = $res->fetch_assoc()) {
$abteilungen[] = $row["Name"];
$abteilungenIDs[] = $row["Abteilungen"];
}
$res = $mysqli->query("SELECT l.Personalgruppen, p.Name FROM link_Personal_Personalgruppen l LEFT JOIN Personalgruppen p ON p.ID=l.Personalgruppen WHERE l.Personal='".$userID."'");
$gruppenIDs = array(null);
while ($row = $res->fetch_assoc()) {
$gruppen[] = $row["Name"];
$gruppenIDs[] = $row["Personalgruppen"];
}
// Terminaktion abarbeiten
$confirm = "";
if (isset($input["termin"], $input["action"], $input["secToken"]) && $input["secToken"]==$_SESSION["secTokenVerify"]) {
$qry = "SELECT t.ID tID, t.Beginn, t.Ausgelost, IF(t.Beginn<NOW(), 1, 0) vorbei, tpv.MaxTeilnehmer, d.Abteilung, t.Personalgruppe, b.Name privName, "
."(SELECT COUNT(*) FROM Terminteilnahmen tln WHERE Termin=t.ID AND Status>=1) num, "
."(SELECT Status FROM Terminteilnahmen tln WHERE Termin=t.ID AND Personal = ?) Status "
.", (SELECT COUNT(*) FROM Terminteilnahmen t4 LEFT JOIN Termine t5 ON t5.ID=t4.Termin "
." WHERE t4.Personal=? AND t5.ID!=t.ID AND t5.Terminart=t.Terminart "
." AND t5.Beginn BETWEEN t.Beginn - INTERVAL 7 DAY AND t.Beginn + INTERVAL 7 DAY) naheDienste "
."FROM Termine t "
."LEFT JOIN Dienstpläne d ON d.ID=t.Dienstplan "
."LEFT JOIN Terminplatzvergabe tpv ON tpv.ID=t.Platzvergabe "
."LEFT JOIN Terminarten ta ON ta.ID = t.Terminart "
."LEFT JOIN Berechtigungen b ON ta.Verwaltungsrecht = b.ID "
."WHERE t.ID = ?";
if ($stmt = $mysqli->prepare($qry)) {
$stmt->bind_param("iii", $userID, $userID, $input["termin"]);
$stmt->execute();
$row = $stmt->get_result()->fetch_assoc();
$stmt->close();
// Mögliche Rechte zum Bearbeiten
$possiblePrivileges = array("DARF_DIENSTE_VERWALTEN");
if (null!==$row["privName"]) {
$possiblePrivileges[] = $row["privName"];
}
// Unprivilegierte Aktionen
if ("join"==$input["action"] && "0"==$row["vorbei"] &&
((in_array($row["Abteilung"], $abteilungenIDs) && in_array($row["Personalgruppe"], $gruppenIDs) && intVal($row["naheDienste"])==0) || lgnCheckRight($mysqli, $possiblePrivileges, $userID))) {
// Möchte beitreten
if ($row["Ausgelost"]=="1" && (intVal($row["num"])<intVal($row["MaxTeilnehmer"]) || "0"==$row["MaxTeilnehmer"])) {
$mysqli->query("REPLACE INTO Terminteilnahmen (Termin, Personal, Status) VALUES ('".$row["tID"]."', '".$userID."', 1)");
informParticipantFromID($mysqli, $row["tID"], $userID, true);
markOrSendParticipantsList($mysqli, $row["tID"]);
} else {
$mysqli->query("REPLACE INTO Terminteilnahmen (Termin, Personal, Status) VALUES ('".$row["tID"]."', '".$userID."', 0)");
}
} else if ("leave"==$input["action"] && "0"==$row["vorbei"]) {
// Möchte verlassen
$mysqli->query("DELETE FROM Terminteilnahmen WHERE Termin = ".$row["tID"]." AND Personal = ".$userID);
if (1==$mysqli->affected_rows && "1"==$row["Ausgelost"]) {
markOrSendParticipantsList($mysqli, $row["tID"]);
}
} else if (lgnCheckRight($mysqli, $possiblePrivileges) || "2"==$row["Status"]) {
// Privilegierte Aktionen
if ("remove"==$input["action"]) {
// Teilnehmer soll entfernt werden
if (isset($input["target"], $input["confirm"])) {
// Entferne Teilnehmer
$qry = "DELETE FROM Terminteilnahmen WHERE Termin = ? AND Personal = ?";
if ($stmt = $mysqli->prepare($qry)) {
$stmt->bind_param("ii", $row["tID"], $input["target"]);
$stmt->execute();
if (1==$stmt->affected_rows && "1"==$row["Ausgelost"]) {
informParticipantFromID($mysqli, $row["tID"], $input["target"], false);
markOrSendParticipantsList($mysqli, $row["tID"]);
}
}
}
} else if ("add"==$input["action"] && isset($input["target"], $input["stage"], $input["confirm"])) {
// Teilnehmer soll hinzugefügt werden
$qry = "REPLACE INTO Terminteilnahmen VALUES (?, ?, ?)";
if ($stmt = $mysqli->prepare($qry)) {
$stmt->bind_param("iii", $row["tID"], $input["target"], $input["stage"]);
$stmt->execute();
if (1==$stmt->affected_rows && "1"==$row["Ausgelost"]) {
informParticipantFromID($mysqli, $row["tID"], $input["target"], true);
markOrSendParticipantsList($mysqli, $row["tID"]);
}
}
}
if (("edit"==$input["action"] || "add"==$input["action"]) && (!isset($input["confirm"]) || "addmore"==$input["confirm"])) {
// Bestätigung abfragen
$addqry = "SELECT p.ID,Vornamen,Nachnamen,tln.Status FROM Personal p LEFT JOIN Terminteilnahmen tln ON tln.Personal=p.ID AND tln.Termin = ".$row["tID"]." ";
if (isset($input["target"]) && !isset($input["confirm"])) {
$addqry.= "WHERE p.ID = ? ";
$confirm = "Teilnahmestatus des Kameraden ändern zu?<br />";
} else {
$confirm = "Kameraden zum Termin hinzufügen?<br />";
}
$addqry.= "ORDER BY Nachnamen ASC, Vornamen ASC";
if ($stmt = $mysqli->prepare($addqry)) {
if (isset($input["target"]) && !isset($input["confirm"])) {
$stmt->bind_param("i", $input["target"]);
}
$stmt->execute();
$addres = $stmt->get_result();
//$stmt->close();
$confirm.= "<form method='get' action='?page=###PAGEMAIN###'><select name='target'>";
$status = 1;
while ($addrow = $addres->fetch_assoc()) {
$confirm.= "<option value='".$addrow["ID"]."'>".$addrow["Nachnamen"].", ".$addrow["Vornamen"]."</option>\n";
if ("edit"==$input["action"]) {
$status = $addrow["Status"];
}
}
$confirm.= "</select><br /><input type=hidden name='termin' value='".$row["tID"]."' />"
.("add"==$input["action"]
? "<input type=hidden name='action' value='add' />"
: "<input type=radio name='action' value='remove' /> Entfernen<br /><input type=radio name='action' value='add' checked />")
."<select name='stage'><option value='0'".($status=="0" ? " selected" : "").">Warteliste</option>"
.("1"==$row["Ausgelost"] ? "<option value='1'".($status=="1" || $status===null ? " selected" : "").">Teilnehmer</option>" : "")
."<option value='2'".($status=="2" ? " selected" : "").">Leitend</option></select><br />"
."<button type=submit name='confirm' value='addone'>Bestätigen</button><br />"
.("add"==$input["action"] ? "<button type=submit name='confirm' value='addmore'>Bestätigen und mehr hinzufügen</button>" : "")
."<input type=hidden name='secToken' value='###SECTOKEN###' /></form>";
} else {
addError("Mysql", $mysqli->error);
}
}
} // /Privilegierte Aktionen
} // /Termin existiert
// TODO: Corona-Unterweisung
// INSERT IGNORE INTO link_Ausbildungen_Personal SELECT DISTINCT 9, Personal FROM Terminteilnahmen t WHERE Status=1
} // /Terminaktion
// Termine auflisten und Anmeldestatus anzeigen
$tpl["list"] = tplExtrSection($tpl["main"], "###DIENSTE.LIST###");
// Bestätigungen anzeigen oder verstecken
if ($confirm!="") {
$confirm_tpl = tplExtrSection($tpl["list"], "###DIENSTE.LIST.CONFIRM###");
$confirm = tplReplMarker($confirm_tpl, "###DIENSTE.LIST.CONFIRM.TEXT###", $confirm);
}
$tpl["list"] = tplReplSection($tpl["list"], "###DIENSTE.LIST.CONFIRM###", $confirm);
$monthsback = $input["monthsback"] ?? 0;
$tpl["list"] = tplReplMarker($tpl["list"], "###DIENSTE.LIST.DEPARTMENTS###", implode(", ", $abteilungen));
$tpl["list"] = tplReplMarker($tpl["list"], "###DIENSTE.LIST.GROUPS###", implode(", ", $gruppen));
$tpl["list"] = tplReplMarker($tpl["list"], "###DIENSTE.LIST.NEWMONTHSBACK###", $monthsback+2);
$dnst_list_entry_tpl = tplExtrSection($tpl["list"], "###DIENSTE.LIST.ENTRY###");
$dnst_list_entry = "";
$qry = "SELECT t.ID, t.Beginn, t.Ende, t.Ort, t.Thema, t.Verantwortliche, t.Ausgelost, t.Personalgruppe, IF(t.Beginn<NOW(), 1, 0) vorbei, pv.MaxTeilnehmer, "
."ta.Name taName, tln.Status, ab.ID abID, ab.Name abName, pg.Name pgName, b.Name privName "
.", (SELECT COUNT(*) FROM Terminteilnahmen t2 WHERE t2.Termin=t.ID AND t2.Status>=1) numDabei "
.", (SELECT COUNT(*) FROM Terminteilnahmen t3 WHERE t3.Termin=t.ID AND t3.Status=0) numWill "
.", (SELECT COUNT(*) FROM Terminteilnahmen t4 LEFT JOIN Termine t5 ON t5.ID=t4.Termin "
." WHERE t4.Personal=? AND t5.ID!=t.ID AND t5.Terminart=t.Terminart "
." AND t5.Beginn BETWEEN t.Beginn - INTERVAL 7 DAY AND t.Beginn + INTERVAL 7 DAY) naheDienste "
."FROM Termine t "
."LEFT JOIN Terminplatzvergabe pv ON pv.ID=t.Platzvergabe "
."LEFT JOIN Terminarten ta ON ta.ID=t.Terminart "
."LEFT JOIN Berechtigungen b ON b.ID=ta.Verwaltungsrecht "
."LEFT JOIN Dienstpläne d ON d.ID=t.Dienstplan "
."LEFT JOIN Abteilungen ab ON ab.ID=d.Abteilung "
."LEFT JOIN Personalgruppen pg ON pg.ID=t.Personalgruppe "
."LEFT JOIN Terminteilnahmen tln ON t.ID=tln.Termin AND tln.Personal = ? "
."WHERE t.Ende > NOW() - INTERVAL ? MONTH "
."ORDER BY t.Beginn ASC ";
if ($stmt = $mysqli->prepare($qry)) {
$stmt->bind_param("iii", $userID, $userID, $monthsback);
$stmt->execute();
$res = $stmt->get_result();
while ($row = $res->fetch_assoc()) {
$entry = $dnst_list_entry_tpl;
$restrictions = $row["MaxTeilnehmer"]!==null && $row["MaxTeilnehmer"]>0 ? "Auf ".$row["MaxTeilnehmer"]." Plätze begrenzt!" : "Keine Platzbegrenzung.";
$terminPrivileges = $row["privName"]!==null ? array("DARF_DIENSTE_VERWALTEN", $row["privName"]) : "DARF_DIENSTE_VERWALTEN";
$replace = array(
"###DIENSTE.LIST.ENTRY.ID###" => $row["ID"],
"###DIENSTE.LIST.ENTRY.BEGIN###" => $row["Beginn"],
"###DIENSTE.LIST.ENTRY.BEGIN.DATE###" => strftime("%a, %d.%m.%Y", strtotime($row["Beginn"])),
"###DIENSTE.LIST.ENTRY.BEGIN.TIME###" => strftime("%H:%M", strtotime($row["Beginn"])),
"###DIENSTE.LIST.ENTRY.END###" => $row["Ende"],
"###DIENSTE.LIST.ENTRY.END.DATE###" => strftime("%d.%m.%Y", strtotime($row["Ende"])),
"###DIENSTE.LIST.ENTRY.END.TIME###" => strftime("%H:%M", strtotime($row["Ende"])),
"###DIENSTE.LIST.ENTRY.TYPE###" => $row["taName"],
"###DIENSTE.LIST.ENTRY.DEPARTMENT###" => $row["abName"],
"###DIENSTE.LIST.ENTRY.TOPIC###" => $row["Thema"],
"###DIENSTE.LIST.ENTRY.RESTRICTIONS###" => $restrictions
);
if ((in_array($row["abID"], $abteilungenIDs) && in_array($row["Personalgruppe"], $gruppenIDs)) || lgnCheckRight($mysqli, $terminPrivileges)) {
$linkJoin = "<a href='?main=###PAGEMAIN###&termin=".$row["ID"]."&action=join&secToken=###SECTOKEN###'><li class='dienste_button'>###NAME### <img src='res/add.png' /></li></a>";
$linkLeave = "<a href='?main=###PAGEMAIN###&termin=".$row["ID"]."&action=leave&secToken=###SECTOKEN###'><li class='dienste_button'>###NAME### <img src='res/cancel.png' /></li></a>";
if (intVal($row["naheDienste"])>0) {
$replace["###DIENSTE.LIST.ENTRY.ALLOWED###"] = "<img src='res/warn.png' />";
} else {
$replace["###DIENSTE.LIST.ENTRY.ALLOWED###"] = "<img src='res/check.png' />";
}
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = "";
$replace["###DIENSTE.LIST.ENTRY.ACTIONNAME###"] = "";
if ($row["vorbei"]=="0" && $row["Ausgelost"]=="0") {
// Noch nicht ausgelost
if ("1"==$row["Status"] || "2"==$row["Status"]) {
// Abmeldung
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = tplReplMarker($linkLeave, "###NAME###", "Abmelden");
} else if (intVal($row["naheDienste"])==0 || lgnCheckRight($mysqli, $terminPrivileges)) {
// Anmeldung
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = tplReplMarker($linkJoin, "###NAME###", "Anmelden");
}
} else if ($row["vorbei"]=="0") {
// Auslosung bereits geschehen, Dienst aber noch nicht gestartet
if ("1"==$row["Status"] || "2"==$row["Status"]) {
// Dabei: Abmeldung möglich
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = tplReplMarker($linkLeave, "###NAME###", "Abmelden");
} else if (("0"==$row["MaxTeilnehmer"] || $row["numDabei"]<$row["MaxTeilnehmer"]) && (intVal($row["naheDienste"])==0 || lgnCheckRight($mysqli, $terminPrivileges))) {
// Nicht dabei und Plätze frei: Mitmachen möglich
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = tplReplMarker($linkJoin, "###NAME###", "Mitmachen");
} else if ($row["Status"]==null && (intVal($row["naheDienste"])==0 || lgnCheckRight($mysqli, $terminPrivileges))) {
// Nicht auf Warteliste und keine Plätze frei: Warteliste möglich
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = tplReplMarker($linkJoin, "###NAME###", "Warteliste eintragen");
}
}
} else {
$reason = in_array($row["abID"], $abteilungenIDs) ? "Kein Mitglied der Gruppe: ".$row["pgName"] : "Falsche Abteilung: ".$row["abName"];
$replace["###DIENSTE.LIST.ENTRY.ALLOWED###"] = "<img src='res/uncheck.png' title='".$reason."' />";
$replace["###DIENSTE.LIST.ENTRY.ACTION###"] = "";
}
if ("2" == $row["Status"] || lgnCheckRight($mysqli, $terminPrivileges)) {
$replace["###DIENSTE.LIST.ENTRY.ACTION###"].= "<a href='?main=###PAGEMAIN###&termin=".$row["ID"]."&action=add&secToken=###SECTOKEN###'>"
."<li class='dienste_button'>Teilnehmer hinzufügen <img src='res/add.png' /></li></a> ";
}
// Kandidatenliste
$cqry = "SELECT p.*,GROUP_CONCAT(a.Kürzel) ausb, tln.Status "
."FROM Terminteilnahmen tln "
."LEFT JOIN Personal p ON p.ID=tln.Personal "
."LEFT JOIN link_Ausbildungen_Personal l ON l.Personal=p.ID LEFT JOIN Ausbildungen a ON a.ID=l.Ausbildungen "
."WHERE tln.Termin = '".$row["ID"]."' GROUP BY p.ID ORDER BY tln.Status DESC, p.Pool DESC, p.Nachnamen ASC, a.ID ASC";
$cres = $mysqli->query($cqry);
$chosen = array();
$want = array();
$responsibles = array();
if ($cres) {
while ($cand = $cres->fetch_assoc()) {
$name = substr($cand["Vornamen"],0,1).". ".$cand["Nachnamen"];
$line = $name;
$ausb = explode(",", $cand["ausb"]);
$feats = "";
if (in_array("KF", $ausb)) { //Kraftfahrer
//$feats.= "🚒"; // <- There is a unicode fire engine in between the quotes
$feats.= "<img src='res/truck.png' />";
}
/*if (in_array("CU", $ausb)) { //Corono Unterweisung
$feats.= "☣️"; // <- There is a unicode biohazard symbol in between the quotes
}*/
if ($feats != "") {
$line.= " "./*"(".*/$feats/*.")"*/;
}
$line = "<a href='?main=###PAGEMAIN###&termin=".$row["ID"]."&action=edit&target=".$cand["ID"]."&secToken=###SECTOKEN###'><li>".$line." <img src='res/edit.png' /></li></a>";
switch ($cand["Status"]) {
case "2":
$responsibles[] = $name;
$chosen[] = "<b>".$line."</b>";
break;
case "1":
$chosen[] = $line;
break;
case "0":
$want[] = $line;
break;
}
}
$cres->close();
} else {
addError("mysql", $mysqli->error);
}
$replace["###DIENSTE.LIST.ENTRY.RESPONSIBLES###"] = implode(" / ", $responsibles);
$candidates = "";
if (lgnCheckRight($mysqli, $terminPrivileges) || 2 == $row["Status"]) {
$candidates = tplExtrSection($entry, "###DIENSTE.LIST.ENTRY.CANDIDATES###");
if (count($want)>0) {
$candidates = tplReplMarker($candidates, "###DIENSTE.LIST.ENTRY.CANDIDATES.WANT###", implode("", $want));
} else {
$candidates = tplReplSection($candidates, "###DIENSTE.LIST.ENTRY.CANDIDATES.HASJOIN###", "");
}
if (count($chosen)>0) {
$candidates = tplReplMarker($candidates, "###DIENSTE.LIST.ENTRY.CANDIDATES.CHOSEN###", implode("", $chosen));
} else {
$candidates = tplReplSection($candidates, "###DIENSTE.LIST.ENTRY.CANDIDATES.HASREST###", "");
}
}
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.CANDIDATES###", $candidates);
//Anmeldung
if ((!in_array($row["abID"], $abteilungenIDs) || !in_array($row["Personalgruppe"], $gruppenIDs)) && !lgnCheckRight($mysqli, $terminPrivileges)) {
// Keine Anmeldung zugelassen, da falsche Gruppe
$answer = "FOREIGN";
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.REGISTRATION###", "");
} else if ($row["MaxTeilnehmer"]===null) {
// Es gibt gar keine Anmeldung, der Dienst ist für alle offen
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.CANDIDATES.HASREST###", "");
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.CANDIDATES.HASJOIN###", "");
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.REGISTRATION###", "");
$answer = "NOLOTTERY";
} else {
// Anmeldung ist möglich bzw. erwünscht
if ($row["MaxTeilnehmer"]=="0") {
// Gibt aber keine Beschränkung, daher Warteliste ausblenden
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.CANDIDATES.HASJOIN###", "");
}
$freePlaces = intVal($row["MaxTeilnehmer"]) - intVal($row["numDabei"]);
if ("1"==$row["Ausgelost"] && $freePlaces>0) {
$entry = tplReplMarker($entry, "###DIENSTE.LIST.ENTRY.FREE.NUM###", $freePlaces);
} else {
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.FREE###", "");
}
if (2 == $row["Status"]) {
$answer = "LEAD";
} else if (1 === $row["Status"] || (0 === $row["Status"] && 0 === $row["MaxTeilnehmer"])) {
// TODO: Teilnehmer bei Diensten ohne Begrenzung auf Dabei setzen, nicht auf Will
$answer = "CAN";
} else if (0 === $row["Status"] && 1 === $row["Ausgelost"]) {
$answer = "WAIT";
} else if (0 === $row["Status"] && 0 === $row["Ausgelost"]) {
$answer = "WANTS";
} else {
$answer = "ADD";
}
}
$entry = tplReplSection($entry, "###DIENSTE.LIST.ENTRY.COMES", tplExtrSection($entry, "###DIENSTE.LIST.ENTRY.COMES.".$answer."###"));
$dnst_list_entry.= tplReplMarkerArray($entry, $replace);
}
$stmt->close();
} else {
$dnst_list_entry = $mysqli->error;
}
$tpl["list"] = tplReplSection($tpl["list"], "###DIENSTE.LIST.ENTRY###", $dnst_list_entry);
}
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTE.SHOW###", $tpl["show"]);
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTE.LIST###", $tpl["list"]);
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTE.LIST###", $tpl["list"]);
$output["main"] = $tpl["main"];
?>

View File

@ -0,0 +1,9 @@
var count = 1;
function addInviteAddRow(row) {
var tableRef = document.getElementById('invite_add').getElementsByTagName('tbody')[0];
// Insert a row in the table at the last row
tableRef.insertAdjacentHTML('beforeend', row.replace(/###COUNT###/g, count));
count++;
}

View File

@ -0,0 +1,12 @@
var inviteListShowComers = true;
function toggleInviteListComers()
{
var elements = document.getElementsByClassName('invite_list_comes_0');
var display = inviteListShowComers ? "table-row" : "none";
for (var i = 0; i<elements.length; i++)
{
elements[i].style.display = display;
}
inviteListShowComers = !inviteListShowComers;
}

View File

@ -0,0 +1,12 @@
function setInviteRsvpChoice(id, html) {
document.getElementById(id).innerHTML = html;
}
function setInviteRsvpChoiceS(that, id, htmlset, htmlsetno) {
if (that.value=='1') {
document.getElementById('invite_rsvp_guest_'+id+'_eats_td').innerHTML = htmlset;
} else {
document.getElementById('invite_rsvp_guest_'+id+'_eats_td').innerHTML = htmlsetno;
}
}

118
pgs/dienste/lib.php Normal file
View File

@ -0,0 +1,118 @@
<?php
function printTeilnehmer($val) {
$ret = "<tr><td>".$val["Nachnamen"].", ".$val["Vornamen"]."</td><td>";
$traits = array();
if ($val["ZF"]) $traits[] = "ZF";
if ($val["GF"]) $traits[] = "GF";
if ($val["KF"]) $traits[] = "KF";
if ($val["AGT"]) $traits[] = "AGT";
if ($val["TH"]) $traits[] = "TH";
if (!$val["TM"]) $traits[] = "Kein Grundlehrgang";
if (count($traits)) $ret.= implode(", ", $traits);
$ret.= "</td><td>Corona-Unterweisung: ".($val["CoronaUnt"] ? "Ja" : "Nein")."</td>"
."<td>".($val["Teilnehmer"] ? "Dabei" : "Will")."</td></tr>\n";
return $ret;
}
function informParticipant($name, $mail, $can, $dienst, $verantwortliche) {
$text = "Hallo ".$name."!<br/><br/>\nDu hast dich für ".$dienst." angemeldet.<br/><br/>";
if ($can) {
$text.= "Du wurdest zu diesem Dienst als Teilnehmer ausgelost und <b>DARFST KOMMEN</b>. Sei bitte pünktlich und bring eine Maske mit!<br/>"
."Wenn Du dich am Tag des Dienstes nicht gesund fühlst, bleib zuhause! Wenn Du aus welchem Grund auch immer doch nicht kommen kannst, "
."teile dieses bitte unverzüglich deinen Diensthabenden mit: ".$verantwortliche."<br/><br/>\n";
} else {
$text.= "Leider hattest Du diesmal Pech und <u>DARFST N I C H T KOMMEN</u>. Dafür wirst Du bei den nächsten Verlosungen bevorzugt.<br/><br/>\n";
}
$text.= "Viele Grüße vom Webserver der OF Innenstadt!";
emlSendEmail($mail, "Ergebnis der Platzvergabe für ".$dienst, $text);
}
function informParticipantFromID($mysqli, $terminID, $personalID, $can) {
$qry = "SELECT Beginn,Thema,Verantwortliche,a.Name FROM Termine t LEFT JOIN Terminarten a ON a.ID = t.Terminart WHERE t.ID = '".$terminID."'";
$res = $mysqli->query($qry);
$termin = $res->fetch_assoc();
$qry = "SELECT Vornamen,Login FROM Personal p WHERE p.ID = '".$personalID."'";
$res = $mysqli->query($qry);
if ($personal = $res->fetch_assoc())
informParticipant($personal["Vornamen"], $personal["Login"]."@feuerwehr-bs.net", $can, $termin["Name"]." am ".date("d.m.Y H:i", strtotime($termin["Beginn"])), $termin["Verantwortliche"]);
}
function markOrSendParticipantsList($mysqli, $terminID) {
$mysqli->query("UPDATE Termine SET TeilnahmeGeändert=1 WHERE Beginn > NOW() + INTERVAL 1 DAY AND ID=".$terminID);
if ($mysqli->affected_rows==0) {
sendParticipantsListToResponsibles($mysqli, $terminID);
}
}
function sendParticipantsListToResponsibles($mysqli, $terminID) {
$qry = "SELECT t.Beginn,IF(t.Beginn>=NOW(),1,0) nichtvorbei,t.Thema,t.Verantwortliche,a.Name as aName FROM Termine t "
."LEFT JOIN Terminarten a ON a.ID=t.Terminart "
."WHERE t.ID='".$terminID."'";
$res = $mysqli->query($qry);
$tmrow = $res->fetch_assoc();
if ("1" == $tmrow["nichtvorbei"]) {
// Generate participants list
$qry = "SELECT p.ID,p.Login,p.Nachnamen,p.Vornamen,po.Name poolName,k.Kürzel kom,GROUP_CONCAT(a.Kürzel) ausbStr, tln.Status "
."FROM Terminteilnahmen tln "
."LEFT JOIN Personal p ON p.ID=tln.Personal "
."LEFT JOIN Pools po ON po.ID=p.Pool "
."LEFT JOIN Kommandofunktionen k ON k.ID=p.Kommandofkt "
."LEFT JOIN link_Ausbildungen_Personal lap ON lap.Personal=p.ID "
."LEFT JOIN Ausbildungen a ON a.ID=lap.Ausbildungen "
."WHERE tln.Termin='".$terminID."' "
."GROUP BY p.ID ORDER BY tln.Status DESC, p.Pool DESC";
$res = $mysqli->query($qry);
$status = "";
$recipients = array();
$liste = "<h3>Teilnahmeliste für ".$tmrow["aName"]." am ".date("d.m.Y H:i", strtotime($tmrow["Beginn"])).": ".$tmrow["Thema"]."</h3>\n<table border=1>\n";
$markedCauser = false;
$liste.= "<tr><th>Name</th><th>Funktionen</th><th>Corona-Unterweisung</th></tr>\n";
while ($row = $res->fetch_assoc()) {
if ($status!=$row["Status"]) {
$status = $row["Status"];
if ("2" == $status) {
$liste.= "<tr><th colspan=3>Diensthabende</th></tr>\n";
} else if ("1" == $status) {
$liste.= "<tr><th colspan=3>Erlaubte Teilnehmer</th></tr>\n";
} else if ("0" == $status) {
$liste.= "<tr><th colspan=3>Weitere Interessenten</th></tr>\n";
}
}
$liste.= "<tr><td>".$row["Nachnamen"].", ".$row["Vornamen"]."</td><td>";
$ausb = explode(",", $row["ausbStr"]);
$traits = array();
if ($row["kom"]!=null) $traits[] = $row["kom"];
if (in_array("KF", $ausb)) $traits[] = "KF";
if (in_array("MA", $ausb)) $traits[] = "MA";
if (in_array("AGT", $ausb)) $traits[] = "AGT";
if (in_array("TH", $ausb)) $traits[] = "TH";
if (!in_array("TM1", $ausb)) $traits[] = "Ohne TM1";
if (count($traits)) $liste.= implode(", ", $traits);
$liste.= "</td><td>".(in_array("CU", $ausb) ? "Ja" : "Nein")."</td></tr>\n";
if ("2" == $row["Status"]) {
$recipients[] = $row["Login"]."@feuerwehr-bs.net";
}
}
$liste.= "</table>\n";
if (!in_array("nils.otterpohl@feuerwehr-bs.net", $recipients))
$recipients[] = "nils.otterpohl@feuerwehr-bs.net";
foreach ($recipients as $recipient) {
emlSendEmail($recipient, "Teilnahmeliste - Dienst ".strftime("%a, den %d.%m.%Y um %H:%M", strtotime($tmrow["Beginn"])), $liste);
}
$mysqli->query("UPDATE Termine SET TeilnahmeGeändert = 0 WHERE ID = ".$terminID);
return $liste;
}
return "";
}
?>

79
pgs/dienste/main.css Normal file
View File

@ -0,0 +1,79 @@
/* pgs/invite/invite.css */
div.confirm {
padding: 1em;
background-color: yellow;
margin-bottom: 1em;
}
li img {
height: 0.8em;
}
.dienste_list_entry div {
border-bottom: 0;
border-left: 0.1em solid #000000;
border-right: 0.1em solid #000000;
border-top: 1px dashed #d0d0d0;
width: 100%;
padding: 0.2em;
}
.dienste_list_entry:last-of-type div:last-of-type {
border-bottom: 0.1em solid #000000;
width: 100%;
padding: 0.2em;
}
.dienste_list_entry div.dienste_title_row {
border-top: 0.1em solid #000000;
background-color: #d0d0d0;
}
.dienste_list_entry ul {
padding: 0;
margin: 0;
list-style: none;
}
.dienste_list_entry ul a {
text-decoration: none;
color: #000000;
}
.dienste_list_entry li {
display: inline-block;
padding: 0.2em;
margin: 0.2em;
background-color: #eeeeee;
border-radius: 0.2em;
}
.dienste_list_entry div.dienste_title_row li {
background-color: #ffffff;
}
.dienste_list_entry li img {
height: 0.8em;
}
.dienste_list_entry a li {
border: 1px solid #000000;
}
.dienste_list_entry .dienste_list_desc {
background-color: #ffffff;
font-weight: bold;
}
.dienste_list_entry .dienste_answer_good {
background-color: green;
font-weight: bold;
}
.dienste_list_entry .dienste_answer_bad {
background-color: red;
}
.dienste_list_entry .dienste_answer_pending {
background-color: lightblue;
}
.dienste_list_entry .dienste_answer_not {
background-color: white;
}
.dienste_list_entry .dienste_answer_lead {
background-color: orange;
font-weight: bold;
}
.dienste_list_entry .dienste_answer_free {
background-color: green;
font-weight: bold;
}
.dienste_list_entry .dienste_button {
/*float:right;*/
}

69
pgs/dienste/main.html Normal file
View File

@ -0,0 +1,69 @@
<!-- tpl/main.html -->
<!-- ###DIENSTE### START -->
<!-- ###DIENSTE.SHOW### START -->
<article>
<a class="toggleVisibility" href="javascript: toggleVisibility('dienste_show_button', 'dienste_show_anleitung')"><h1>Anleitung <img id="dienste_show_button" src="res/show.png" /></h1></a>
<div id="dienste_show_anleitung" class="toggleVisibility" style="display: none;">
<p>Hier werden die kommenden Dienste aufgelistet. Zu einigen davon kannst bzw. musst Du dich anmelden und zu einigen bist Du nicht zugelassen. Lies daher bitte die folgenden Hinweise:</p>
<ol>
<li>Du darfst zu einem Termin nur kommen, wenn dies auch so in der Liste unten steht: &quot;Du darfst kommen!&quot;</li>
<li>Bei Terminen mit mehr Interessenten als Pl&auml;tzen wird gelost, zur Zeit eine Woche vor Dienstbeginn.</li>
<li>Corona-Dienste werden zwei Tage vor Beginn f&uuml;r alle Gruppen freigegeben, falls noch Pl&auml;tze frei sind.</li>
<li>Erscheine <b>p&uuml;nktlich</b> zum Dienstbeginn! Bring eine <b>Maske</b> mit!</li>
<li><img src="res/check.png" /> = Zugelassen zum Dienst <img src="res/uncheck.png" /> = Nicht zugelassen<br />
<img src="res/warn.png" /> = Du bist bereits zu einem anderen Dienst 7 Tage vorher oder nachher angemeldet. Denke daran, dass wir die Gruppeneinteilung auch als Infektionsschutz eingerichtet haben.</li>
</ol>
</div>
</article>
<!-- ###DIENSTE.SHOW### END -->
<!-- ###DIENSTE.LIST### START -->
<article>
<!-- ###DIENSTE.LIST.CONFIRM### START -->
<div class="confirm">Bitte best&auml;tige den Vorgang: ###DIENSTE.LIST.CONFIRM.TEXT###</div>
<!-- ###DIENSTE.LIST.CONFIRM### END -->
<p>
Deine Abteilung(en): ###DIENSTE.LIST.DEPARTMENTS###<br />
Deine Gruppe(n): ###DIENSTE.LIST.GROUPS###<br />
<a href="?main=###PAGEMAIN###&amp;monthsback=###DIENSTE.LIST.NEWMONTHSBACK###">&Auml;ltere Dienste anzeigen</a>
</p>
<!-- ###DIENSTE.LIST.ENTRY### START -->
<div class="dienste_list_entry">
<div class="dienste_title_row">
<ul>
<li>###DIENSTE.LIST.ENTRY.ALLOWED###</li>
<li><img src="res/date.png" /> <b>###DIENSTE.LIST.ENTRY.BEGIN.DATE###</b></li>
<li><img src="res/time.png" /> ###DIENSTE.LIST.ENTRY.BEGIN.TIME### - ###DIENSTE.LIST.ENTRY.END.TIME###</li>
<li><img src="res/type.png" /> ###DIENSTE.LIST.ENTRY.TYPE###</li>
<li><img src="res/topic.png" /> ###DIENSTE.LIST.ENTRY.TOPIC###</li>
<li><img src="res/teacher.png" /> ###DIENSTE.LIST.ENTRY.RESPONSIBLES###</li>
</ul>
</div>
<!-- ###DIENSTE.LIST.ENTRY.REGISTRATION### START -->
<div>
<ul>
<li class="dienste_list_desc">↳ ###DIENSTE.LIST.ENTRY.RESTRICTIONS###</li>
<!-- ###DIENSTE.LIST.ENTRY.COMES### START -->
<!-- ###DIENSTE.LIST.ENTRY.COMES.CAN### START --><li class="dienste_answer_good">Du darfst kommen</li><!-- ###DIENSTE.LIST.ENTRY.COMES.CAN### END -->
<!-- ###DIENSTE.LIST.ENTRY.COMES.WAIT### START --><li class="dienste_answer_bad">Auf Warteliste</li><!-- ###DIENSTE.LIST.ENTRY.COMES.WAIT### END -->
<!-- ###DIENSTE.LIST.ENTRY.COMES.WANTS### START --><li class="dienste_answer_pending">Zur Auslosung angemeldet</li><!-- ###DIENSTE.LIST.ENTRY.COMES.WANTS### END -->
<!-- ###DIENSTE.LIST.ENTRY.COMES.ADD### START --><li class="dienste_answer_not">Bei Interesse bitte anmelden</li><!-- ###DIENSTE.LIST.ENTRY.COMES.ADD### END -->
<!-- ###DIENSTE.LIST.ENTRY.COMES.LEAD### START --><li class="dienste_answer_lead">Du leitest diesen Dienst</li><!-- ###DIENSTE.LIST.ENTRY.COMES.LEAD### END -->
<!-- ###DIENSTE.LIST.ENTRY.COMES### END -->
<!-- ###DIENSTE.LIST.ENTRY.FREE### START --><li class="dienste_answer_free">Noch ###DIENSTE.LIST.ENTRY.FREE.NUM### Pl&auml;tze frei</li><!-- ###DIENSTE.LIST.ENTRY.FREE### END -->
###DIENSTE.LIST.ENTRY.ACTION###
</ul>
</div>
<!-- ###DIENSTE.LIST.ENTRY.CANDIDATES### START -->
<!-- ###DIENSTE.LIST.ENTRY.CANDIDATES.HASREST### START -->
<div><ul><li class="dienste_list_desc">↳ D&uuml;rfen:</li>###DIENSTE.LIST.ENTRY.CANDIDATES.CHOSEN###</ul></div>
<!-- ###DIENSTE.LIST.ENTRY.CANDIDATES.HASREST### END -->
<!-- ###DIENSTE.LIST.ENTRY.CANDIDATES.HASJOIN### START -->
<div><ul><li class="dienste_list_desc">↳ Wollen:</li>###DIENSTE.LIST.ENTRY.CANDIDATES.WANT###</ul></div>
<!-- ###DIENSTE.LIST.ENTRY.CANDIDATES.HASJOIN### END -->
<!-- ###DIENSTE.LIST.ENTRY.CANDIDATES### END -->
<!-- ###DIENSTE.LIST.ENTRY.REGISTRATION### END -->
</div>
<!-- ###DIENSTE.LIST.ENTRY### END -->
</article>
<!-- ###DIENSTE.LIST### END -->
<!-- ###DIENSTE### END -->

7
pgs/dienste/module.json Normal file
View File

@ -0,0 +1,7 @@
{
"moduleName" : "Dienste",
"title" : "Dienste",
"show" : 1,
"useRight": null,
"adminRight": "DARF_DIENSTE_VERWALTEN"
}

116
pgs/dienstplaene/index.php Normal file
View File

@ -0,0 +1,116 @@
<?php #pgs/dienste/index.php
$tpl = array(
"main" => tplExtrSection(tplLoadFile("pgs/dienstplaene/main.html"), "DIENSTPLAENE"),
"plans" => "",
"add" => "",
"list" => ""
);
addStyle("pgs/dienstplaene/main.css");
if ($userID = lgnCheckLogin($mysqli)) {
// Lesezeichen zeigen
$tpl["plans"] = tplExtrSection($tpl["main"], "###DIENSTPLAENE.PLANS###");
// Dienstpläne abrufen
$res = $mysqli->query("SELECT d.*, a.Kürzel FROM Dienstpläne d LEFT JOIN Abteilungen a ON a.ID=d.Abteilung ORDER BY d.Jahr DESC, d.Name DESC, a.ID ASC");
$dp_select_tpl = tplExtrSection($tpl["plans"], "###DIENSTPLAENE.PLANS.PLAN###");
$dp_select = "";
while ($row = $res->fetch_assoc()) {
$repl = array(
"###DIENSTPLAENE.PLANS.PLAN.NAME###" => $row["Kürzel"].": ".$row["Jahr"]." - ".$row["Name"],
"###DIENSTPLAENE.PLANS.PLAN.LINK###" => "#dienstplan_".$row["ID"]
);
$dp_select.= tplReplMarkerArray($dp_select_tpl, $repl);
}
$tpl["plans"] = tplReplSection($tpl["plans"], "###DIENSTPLAENE.PLANS.PLAN###", $dp_select);
// Dienstplan hinzufügen
$res = $mysqli->query("SELECT * FROM Abteilungen");
$dp_addtp_tpl = tplExtrSection($tpl["plans"], "###DIENSTPLAENE.PLANS.ADD###");
$dp_addtp_select = "";
while ($row = $res->fetch_assoc()) {
$repl = array(
"###DIENSTPLAENE.PLANS.ADD.ABTEILUNG.ID###" => $row["ID"],
"###DIENSTPLAENE.PLANS.ADD.ABTEILUNG.NAME###" => $row["Name"]
);
$dp_addtp_select.= tplReplMarkerArray($dp_addtp_tpl, $repl);
}
$tpl["plans"] = tplReplSection($tpl["plans"], "###DIENSTPLAENE.PLANS.ADD###", $dp_addtp_select);
// Termin(e) hinzufügen
$tpl["add"] = tplExtrSection($tpl["main"], "###DIENSTPLAENE.ADD###");
// Termine auflisten und Anmeldestatus anzeigen
$tpl["list"] = tplExtrSection($tpl["main"], "###DIENSTPLAENE.LIST###");
$dp_block_tpl = tplExtrSection($tpl["list"], "###DIENSTPLAENE.LIST.BLOCK###");
$dp_entry_tpl = tplExtrSection($dp_block_tpl, "###DIENSTPLAENE.LIST.ENTRY###");
$qry = "SELECT t.ID, t.Beginn, t.Ende, t.Thema, t.Ort, d.ID dID, d.Jahr, d.Name dName, "
."a.Name aName, ta.Name taName, b.Name bName, tpv.Name tpvName, pg.Name pgName, "
."GROUP_CONCAT(CONCAT(LEFT(p.Vornamen, 1), '. ', p.Nachnamen) SEPARATOR ', ') Verantwortliche "
."FROM Termine t "
."LEFT JOIN Dienstpläne d ON d.ID = t.Dienstplan "
."LEFT JOIN Abteilungen a ON a.ID = d.Abteilung "
."LEFT JOIN Terminarten ta ON ta.ID = t.Terminart "
."LEFT JOIN Berechtigungen b ON b.ID = ta.Verwaltungsrecht "
."LEFT JOIN Terminplatzvergabe tpv ON tpv.ID = t.Platzvergabe "
."LEFT JOIN Personalgruppen pg ON pg.ID = t.Personalgruppe "
."LEFT JOIN Terminteilnahmen tln ON tln.Termin = t.ID AND tln.Status >= 2 "
."LEFT JOIN Personal p ON p.ID = tln.Personal "
."GROUP BY t.ID "
."ORDER BY d.Jahr DESC, d.Abteilung ASC, d.Name DESC, t.Beginn ASC ";
$res = $mysqli->query($qry);
$lastdID = null;
$dienstplaene = array();
$entries = array();
$current = null;
while ($row = $res->fetch_assoc()) {
if ($row["dID"]!=$lastdID) {
$repl = array(
"###DIENSTPLAENE.LIST.BLOCK.DID###" => $row["dID"],
"###DIENSTPLAENE.LIST.BLOCK.ANAME###" => $row["aName"],
"###DIENSTPLAENE.LIST.BLOCK.DJAHR###" => $row["Jahr"],
"###DIENSTPLAENE.LIST.BLOCK.DNAME###" => $row["dName"]
);
$current = &$dienstplaene[];
$current = array(
"tpl" => tplReplMarkerArray($dp_block_tpl, $repl),
"entries" => array()
);
$lastdID = $row["dID"];
}
$repl = array(
"###DIENSTPLAENE.LIST.ENTRY.ID###" => $row["ID"],
"###DIENSTPLAENE.LIST.ENTRY.BEGIN###" => $row["Beginn"],
"###DIENSTPLAENE.LIST.ENTRY.BEGIN.DATE###" => strftime("%a, %d.%m.%Y", strtotime($row["Beginn"])),
"###DIENSTPLAENE.LIST.ENTRY.BEGIN.TIME###" => strftime("%H:%M", strtotime($row["Beginn"])),
"###DIENSTPLAENE.LIST.ENTRY.END###" => $row["Ende"],
"###DIENSTPLAENE.LIST.ENTRY.END.DATE###" => strftime("%a, %d.%m.%Y", strtotime($row["Ende"])),
"###DIENSTPLAENE.LIST.ENTRY.END.TIME###" => strftime("%H:%M", strtotime($row["Ende"])),
"###DIENSTPLAENE.LIST.ENTRY.TOPIC###" => $row["Thema"],
"###DIENSTPLAENE.LIST.ENTRY.PLACE###" => $row["Ort"],
"###DIENSTPLAENE.LIST.ENTRY.TYPE###" => $row["taName"],
"###DIENSTPLAENE.LIST.ENTRY.TPVNAME###" => $row["tpvName"],
"###DIENSTPLAENE.LIST.ENTRY.PGNAME###" => $row["pgName"],
"###DIENSTPLAENE.LIST.ENTRY.RESPONSIBLES###" => $row["Verantwortliche"]
);
$current["entries"][] = tplReplMarkerArray($dp_entry_tpl, $repl);
}
$list = "";
foreach ($dienstplaene as $dp) {
$list.= tplReplSection($dp["tpl"], "###DIENSTPLAENE.LIST.ENTRY###", implode("", $dp["entries"]));
}
$tpl["list"] = tplReplSection($tpl["list"], "###DIENSTPLAENE.LIST.BLOCK###", $list);
}
// Template füllen
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTPLAENE.PLANS###", $tpl["plans"]);
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTPLAENE.LIST###", $tpl["list"]);
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTPLAENE.LIST###", $tpl["list"]);
$tpl["main"] = tplReplSection($tpl["main"], "###DIENSTPLAENE.ADD###", $tpl["add"]);
$output["main"] = $tpl["main"];
?>

115
pgs/dienstplaene/lib.php Normal file
View File

@ -0,0 +1,115 @@
<?php
function printTeilnehmer($val) {
$ret = "<tr><td>".$val["Nachnamen"].", ".$val["Vornamen"]."</td><td>";
$traits = array();
if ($val["ZF"]) $traits[] = "ZF";
if ($val["GF"]) $traits[] = "GF";
if ($val["KF"]) $traits[] = "KF";
if ($val["AGT"]) $traits[] = "AGT";
if ($val["TH"]) $traits[] = "TH";
if (!$val["TM"]) $traits[] = "Kein Grundlehrgang";
if (count($traits)) $ret.= implode(", ", $traits);
$ret.= "</td><td>Corona-Unterweisung: ".($val["CoronaUnt"] ? "Ja" : "Nein")."</td>"
."<td>".($val["Teilnehmer"] ? "Dabei" : "Will")."</td></tr>\n";
return $ret;
}
function informParticipant($name, $mail, $can, $dienst, $verantwortliche) {
$text = "Hallo ".$name."!<br/><br/>\nDu hast dich für ".$dienst." angemeldet.<br/><br/>";
if ($can) {
$text.= "Du wurdest zu diesem Dienst als Teilnehmer ausgelost und <b>DARFST KOMMEN</b>. Sei bitte pünktlich und bring eine Maske mit!<br/>"
."Wenn Du dich am Tag des Dienstes nicht gesund fühlst, bleib zuhause! Wenn Du aus welchem Grund auch immer doch nicht kommen kannst, "
."teile dieses bitte unverzüglich deinen Diensthabenden mit: ".$verantwortliche."<br/><br/>\n";
} else {
$text.= "Leider hattest Du diesmal Pech und <u>DARFST N I C H T KOMMEN</u>. Dafür wirst Du bei den nächsten Verlosungen bevorzugt.<br/><br/>\n";
}
$text.= "Viele Grüße vom Webserver der OF Innenstadt!";
emlSendEmail($mail, "Ergebnis der Platzvergabe für ".$dienst, $text);
}
function informParticipantFromID($mysqli, $terminID, $personalID, $can) {
$qry = "SELECT Beginn,Thema,Verantwortliche,a.Name FROM Termine t LEFT JOIN Terminarten a ON a.ID = t.Terminart WHERE t.ID = '".$terminID."'";
$res = $mysqli->query($qry);
$termin = $res->fetch_assoc();
$qry = "SELECT Vornamen,Login FROM Personal p WHERE p.ID = '".$personalID."'";
$res = $mysqli->query($qry);
if ($personal = $res->fetch_assoc())
informParticipant($personal["Vornamen"], $personal["Login"]."@feuerwehr-bs.net", $can, $termin["Name"]." am ".date("d.m.Y H:i", strtotime($termin["Beginn"])), $termin["Verantwortliche"]);
}
function markOrSendParticipantsList($mysqli, $terminID) {
$mysqli->query("UPDATE Termine SET TeilnahmeGeändert=1 WHERE Beginn > NOW() + INTERVAL 1 DAY AND ID=".$terminID);
if ($mysqli->affected_rows==0) {
sendParticipantsListToResponsibles($mysqli, $terminID);
}
}
function sendParticipantsListToResponsibles($mysqli, $terminID) {
$qry = "SELECT t.Beginn,t.Thema,t.Verantwortliche,a.Name as aName FROM Termine t "
."LEFT JOIN Terminarten a ON a.ID=t.Terminart "
."WHERE t.ID='".$terminID."'";
$res = $mysqli->query($qry);
$tmrow = $res->fetch_assoc();
// Generate participants list
$qry = "SELECT p.ID,p.Login,p.Nachnamen,p.Vornamen,po.Name poolName,k.Kürzel kom,GROUP_CONCAT(a.Kürzel) ausbStr, tln.Status "
."FROM Terminteilnahmen tln "
."LEFT JOIN Personal p ON p.ID=tln.Personal "
."LEFT JOIN Pools po ON po.ID=p.Pool "
."LEFT JOIN Kommandofunktionen k ON k.ID=p.Kommandofkt "
."LEFT JOIN link_Ausbildungen_Personal lap ON lap.Personal=p.ID "
."LEFT JOIN Ausbildungen a ON a.ID=lap.Ausbildungen "
."WHERE tln.Termin='".$terminID."' "
."GROUP BY p.ID ORDER BY tln.Status DESC, p.Pool DESC";
$res = $mysqli->query($qry);
$status = "";
$recipients = array();
$liste = "<h3>Teilnahmeliste für ".$tmrow["aName"]." am ".date("d.m.Y H:i", strtotime($tmrow["Beginn"])).": ".$tmrow["Thema"]."</h3>\n<table border=1>\n";
$markedCauser = false;
$liste.= "<tr><th>Name</th><th>Funktionen</th><th>Corona-Unterweisung</th></tr>\n";
while ($row = $res->fetch_assoc()) {
if ($status!=$row["Status"]) {
$status = $row["Status"];
if ("2" == $status) {
$liste.= "<tr><th colspan=3>Diensthabende</th></tr>\n";
} else if ("1" == $status) {
$liste.= "<tr><th colspan=3>Erlaubte Teilnehmer</th></tr>\n";
} else if ("0" == $status) {
$liste.= "<tr><th colspan=3>Weitere Interessenten</th></tr>\n";
}
}
$liste.= "<td>".$row["Nachnamen"].", ".$row["Vornamen"]."</td><td>";
$ausb = explode(",", $row["ausbStr"]);
$traits = array();
if ($row["kom"]!=null) $traits[] = $row["kom"];
if (in_array("KF", $ausb)) $traits[] = "KF";
if (in_array("MA", $ausb)) $traits[] = "MA";
if (in_array("AGT", $ausb)) $traits[] = "AGT";
if (in_array("TH", $ausb)) $traits[] = "TH";
if (!in_array("TM1", $ausb)) $traits[] = "Ohne TM1";
if (count($traits)) $liste.= implode(", ", $traits);
$liste.= "</td><td>".(in_array("CU", $ausb) ? "Ja" : "Nein")."</td></tr>\n";
if ("2" == $row["Status"]) {
$recipients[] = $row["Login"]."@feuerwehr-bs.net";
}
}
$liste.= "</table>\n";
if (!in_array("nils.otterpohl@feuerwehr-bs.net", $recipients))
$recipients[] = "nils.otterpohl@feuerwehr-bs.net";
foreach ($recipients as $recipient) {
emlSendEmail($recipient, "Teilnahmeliste - Dienst ".strftime("%a, den %d.%m.%Y um %H:%M", strtotime($tmrow["Beginn"])), $liste);
}
$mysqli->query("UPDATE Termine SET TeilnahmeGeändert = 0 WHERE ID = ".$terminID);
return $liste;
}
?>

50
pgs/dienstplaene/main.css Normal file
View File

@ -0,0 +1,50 @@
/* pgs/dienstplaene/main.css */
label {
width: 6em;
float: left;
}
li img {
height: 0.8em;
}
.dienstplaene_list_header {
margin: 1em 0;
}
.dienstplaene_list_entry {
border-bottom: 0;
border-left: 0.1em solid #000000;
border-right: 0.1em solid #000000;
border-top: 0.1em solid #000000;
width: 100%;
padding: 0.2em;
}
.dienstplaene_list_entry:first-child {
}
.dienstplaene_list_entry:last-of-type {
border-bottom: 0.1em solid #000000;
width: 100%;
padding: 0.2em;
}
.dienstplaene_list_entry ul {
padding: 0;
margin: 0;
list-style: none;
}
.dienstplaene_list_entry ul a {
text-decoration: none;
color: #000000;
}
.dienstplaene_list_entry li {
display: inline-block;
padding: 0.2em;
margin: 0.2em;
background-color: #eeeeee;
border-radius: 0.2em;
}
.dienstplaene_list_entry li img {
height: 0.8em;
}
.dienstplaene_list_entry a li {
border: 1px solid #000000;
}

View File

@ -0,0 +1,72 @@
<!-- pgs/dienstplaene/main.html -->
<!-- ###DIENSTPLAENE### START -->
<!-- ###DIENSTPLAENE.PLANS### START -->
<article>
<p>
Springe zu Dienstplan:
<select>
<!-- ###DIENSTPLAENE.PLANS.PLAN### START -->
<option value="#dienstplan_###DIENSTPLAENE.PLANS.PLAN.ID###">###DIENSTPLAENE.PLANS.PLAN.NAME###</option>
<!-- ###DIENSTPLAENE.PLANS.PLAN### END -->
</select>
</p>
<a class="toggleVisibility" href="javascript: toggleVisibility('dienstplaene_add_button', 'dienstplaene_add_panel')"><h1>Neuen Dienstplan erstellen <img id="dienstplaene_add_button" src="res/show.png" /></h1></a>
<div id="dienstplaene_add_panel" class="toggleVisibility" style="display:none;">
<form action="post">
<label>Abteilung:</label>
<select name="dienstplaene_add_abteilung">
<!-- ###DIENSTPLAENE.PLANS.ADD### START -->
<option value="###DIENSTPLAENE.PLANS.ADD.ABTEILUNG.ID###">###DIENSTPLAENE.PLANS.ADD.ABTEILUNG.NAME###</option>
<!-- ###DIENSTPLAENE.PLANS.ADD### END -->
</select><br />
<label>Jahr:</label> <input name="dienstplaene_add_jahr" maxlength="4" /><br />
<label>Name:</label> <input name="dienstplaene_add_name" /><br />
<button>Hinzufügen</button><input type="hidden" name="secToken" value="###SECTOKEN###" />
</form>
</div>
</article>
<!-- ###DIENSTPLAENE.PLANS### END -->
<!-- ###DIENSTPLAENE.ADD### START -->
<article>
<a class="toggleVisibility" href="javascript: toggleVisibility('dienste_add_button', 'dienste_add_panel')"><h1>Dienste hinzufügen <img id="dienste_add_button" src="res/show.png" /></h1></a>
<div id="dienste_add_panel" class="toggleVisibility" style="display: none;">
<ul>
<li>Beginn (DateTime-Picker - Rome.js? - Vereinstellung 18 Uhr)</li>
<li>Ende (DateTime-Picker - Rome.js? - Datum gekoppelt an Beginn, Vereinstellung 21 Uhr)</li>
<li>Thema</li>
<li>Ort</li>
<li>Verantwortliche (Multi-Select - aus Personal)</li>
<li>Dienstplan (Select - aus Dienstpläne - ggfs. nach Abteilung filtern)</li>
<li>Terminart (Select - aus Terminarten - ggfs. an Verwaltungsrecht gekoppelt)</li>
<li>Platzvergabe (Select - aus Terminplatzvergabe)</li>
<li>Personalgruppe (Select - aus Personalgruppen - ggfs. nach Abteilung filtern)</li>
</ul>
</div>
</article>
<!-- ###DIENSTPLAENE.ADD### END -->
<!-- ###DIENSTPLAENE.LIST### START -->
<article>
<!-- ###DIENSTPLAENE.LIST.BLOCK### START -->
<div class="dienstplaene_list_header">
<a class="toggleVisibility" href="javascript: toggleVisibility('dienstplan_###DIENSTPLAENE.LIST.BLOCK.DID###_button', 'dienstplan_###DIENSTPLAENE.LIST.BLOCK.DID###')"><h1>###DIENSTPLAENE.LIST.BLOCK.ANAME###: ###DIENSTPLAENE.LIST.BLOCK.DJAHR### - ###DIENSTPLAENE.LIST.BLOCK.DNAME### <img id="dienstplan_###DIENSTPLAENE.LIST.BLOCK.DID###_button" src="res/show.png" /></h1></a>
</div>
<div id="dienstplan_###DIENSTPLAENE.LIST.BLOCK.DID###" style="display:none;">
<!-- ###DIENSTPLAENE.LIST.ENTRY### START -->
<div class="dienstplaene_list_entry">
<ul>
<li><img src="res/date.png" /> <b>###DIENSTPLAENE.LIST.ENTRY.BEGIN.DATE###</b></li>
<li><img src="res/time.png" /> ###DIENSTPLAENE.LIST.ENTRY.BEGIN.TIME### - ###DIENSTPLAENE.LIST.ENTRY.END.TIME###</li>
<li><img src="res/type.png" /> ###DIENSTPLAENE.LIST.ENTRY.TYPE###</li>
<li><img src="res/topic.png" /> ###DIENSTPLAENE.LIST.ENTRY.TOPIC###</li>
<li><img src="res/location.png" /> ###DIENSTPLAENE.LIST.ENTRY.PLACE###</li>
<li><img src="res/teacher.png" /> ###DIENSTPLAENE.LIST.ENTRY.RESPONSIBLES###</li>
<li><img src="res/mechanism.png" /> ###DIENSTPLAENE.LIST.ENTRY.TPVNAME###</li>
<li><img src="res/group.png" /> ###DIENSTPLAENE.LIST.ENTRY.PGNAME###</li>
</ul>
</div>
<!-- ###DIENSTPLAENE.LIST.ENTRY### END -->
</div>
<!-- ###DIENSTPLAENE.LIST.BLOCK### END -->
</article>
<!-- ###DIENSTPLAENE.LIST### END -->
<!-- ###DIENSTPLAENE### END -->

View File

@ -0,0 +1,7 @@
{
"moduleName" : "Dienstpläne",
"title" : "Dienstpläne",
"show" : false,
"useRight": "ADMIN",
"adminRight": "DARF_DIENSTE_VERWALTEN"
}

BIN
res/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
res/cancel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 B

BIN
res/check.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/date.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
res/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 B

8
res/errors.html Normal file
View File

@ -0,0 +1,8 @@
<!-- tpl/errors.html -->
<!-- ###ERRORS### START -->
<div id='errors'>
Es sind Fehler aufgetreten:<br />
<ul>
<!-- ###ERRORENTRY### START --><li>###ERRORMSG###</li><!-- ###ERRORENTRY### END -->
</ul></div>
<!-- ###ERRORS### END -->

BIN
res/frontpage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

BIN
res/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 B

BIN
res/hide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/location.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

175
res/main.css Normal file
View File

@ -0,0 +1,175 @@
/* tpl/main.css */
body {
font-family: arial;
font-size: 20px;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
header {
background: #ffffff url(frontpage.jpg) center no-repeat;
background-size: cover;
/*padding: 1em;*/
width: 100%;
}
header.frontpage {
height: 100vh;
}
header.content {
display: none;
}
#login {
position: absolute;
width: 18em;
left: calc(50% - 9em);
bottom: 5em;
}
#login p {
background-color: #ffffff;
text-align: center;
padding: 0.2em;
border-radius: 0.2em;
}
nav {
vertical-align: middle;
text-align: left;
background-color: #9b0000;
position: sticky;
top: 0;
z-index: 100;
/*width: 100vw;*/
}
nav ul {
padding: 0 0.5em;
margin: 0;
list-style: none;
}
nav a {
color: #ffffff;
}
nav li {
display: inline-block;
padding: 0.5em 0.75em;
font-weight: bold;
margin: 0;
border-top-left-radius: 0.2em;
border-top-right-radius: 0.2em;
}
nav li:hover {
background-color: #ff0000;
}
nav a.current li {
background-color: #ffffff;
color: #9b0000;
}
main {
padding: 0 1.75em;
}
footer {
padding: 0 2em;
background-color: #ffff00;
}
article {
margin: 0 0 2em 0;
max-width: 60em;
}
article:first-of-type {
margin: 2em 0 2em 0;
}
article img {
max-width: 100%;
}
article h1 img {
height: 0.8em;
}
input,button,select {
font-size: 1em;
width: 12em;
}
input[type="radio"],input[type="checkbox"] {
width: auto;
}
input[type="submit"] {
background-color: #9b0000;
color: #ffffff;
}
input.login {
width: 12em;
text-align: center;
border: 0.1em solid #000000;
padding: 0.2em;
margin: 0.1em;
box-sizing: content-box;
font-size: 100%;
}
a {
color: #9b0000;
text-decoration: underline;
}
a.toggleVisibility {
text-decoration: none;
color: #000000;
}
a.toggleVisibility > * {
background-color: #eeeeee;
display: inline;
padding: 0.2em;
border-radius: 0.2em;
}
div.toggleVisibility {
/* background-color: #eeeeee;*/
padding: 0.2em;
/* border-radius: 0.2em;*/
}
div.toggleVisibility > * {
margin-top: 1em;
}
table {
font-family: arial;
border-collapse: collapse;
border: 1px solid #000000;
width: 100%;
}
table table {
width: auto;
}
td,th {
border-bottom: 1px solid #c0c0c0;
padding: 0.3em;
}
th {
border-top: 1px solid #000000;
background-color: #9b0000;
border-color: #000000;
color: #ffffff;
text-align: left;
}
.important {
color: #ff0000;
font-weight: bold;
}
@media only screen and (orientation: portrait) {
body {
font-size: 5vw;
}
nav {
font-size: 5vw;
}
main {
padding: 0 1em;
}
nav li {
padding: 1em 0.35em;
}
table {
font-size: 5vw;
}
input,button,select {
font-size: 5vw;
}
input[type=radio] {
border: 0px;
height: 1em;
}
}

47
res/main.html Normal file
View File

@ -0,0 +1,47 @@
<!-- tpl/main.html -->
<!DOCTYPE html>
<html>
<head>
<!-- ###DOCUMENT_HEAD### START -->
<meta charset="utf-8" />
<meta http-equiv="expires" content="0">
<meta name="author" content="Nils Otterpohl" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>###TITLE###</title>
<!-- ###CSS### START --><link rel='stylesheet' type='text/css' href='###CSSFILE###' /><!-- ###CSS### END -->
<!-- ###JS### START --><script src='###JSFILE###'></script><!-- ###JS### END -->
<!-- ###DOCUMENT_HEAD### END -->
</head>
<body>
<header class='###PAGETYPE###'>
<!-- ###LOGIN### START -->
<div id='login'>
<center>
<form action='index.php###PAGEGET###' method='post'>
<input class='login' name='login' autofocus /><br />
<input class='login' name='pass' type='password' /><br />
<input class='login' name='submit' type='submit' value='Einloggen' />
<input type='hidden' name='secToken' value='###SECTOKEN###' />
</form>
</center>
<p>
Anmeldedaten von IServ!<br/>
(vorname.nachname)<br/>
Sollte der Login nicht klappen, bitte versuchen ob die Zugangsdaten auf <a href="https://feuerwehr-bs.net">feuerwehr-bs.net</a> funktionieren und danach bei Nils melden.
</p>
</div>
<!-- ###LOGIN### END -->
</header>
<nav class='###PAGETYPE###'>
<ul>
###NAV###<!-- ###LOGOFF### START --><a href='index.php?userMod=Ausloggen&secToken=###SECTOKEN###'><li>Ausloggen</li></a><!-- ###LOGOFF### END -->
</ul>
</nav>
<footer>
###ERRORS###
</footer>
<main>
###MAIN###
</main>
</body>
</html>

11
res/main.js Normal file
View File

@ -0,0 +1,11 @@
function toggleVisibility(idImg, idDiv) {
var div = document.getElementById(idDiv);
var img = document.getElementById(idImg);
if (div.style.display === "none") {
div.style.display = "block";
img.src = "res/hide.png";
} else {
div.style.display = "none";
img.src = "res/show.png";
}
}

BIN
res/mechanism.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 B

6
res/nav.html Normal file
View File

@ -0,0 +1,6 @@
<!-- tpl/nav.html -->
<!-- ###NAVLINE### START -->
<!-- ###NAVENTRY### START --><a href='###NAVHREF###' class='###NAVCLASS###'><li>###NAVLABEL###</li></a><!-- ###NAVENTRY### END -->
<!-- ###NAVSEPERATOR### START --><!-- ###NAVSEPERATOR### END -->
<!-- ###NAVLINE### END -->

BIN
res/show.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/teacher.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

BIN
res/time.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/topic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

BIN
res/truck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

BIN
res/type.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

BIN
res/uncheck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
res/warn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

12
var/00_mysql.php.dist Normal file
View File

@ -0,0 +1,12 @@
<?php #var/00_mysql.php
//Mysql login
$DBHOST = "localhost";
$DBUSER = "";
$DBPASS = "";
$DBNAME = "";
$mysqli = new mysqli($DBHOST, $DBUSER, $DBPASS, $DBNAME);
$mysqli->set_charset("utf8mb4");
?>

21
var/10_conf.php Normal file
View File

@ -0,0 +1,21 @@
<?php #var/10_conf.php
//Default pages
define("FRAMETPL", "res/main.html");
define("FRAMECSS", "res/main.css");
define("FRAMEJS", "res/main.js");
//define("STARTPAGE", "Dienste");
//Additional stuff
define ("TITLE", "OF Innenstadts-App");
//Login related stuff
define("DESIRED_ITERATIONS", 160000);
//Text related stuff
define("SYM_CIPHER_KEY", "P5SqyQfqmc6qTexW");
// Date and time locale
setlocale(LC_TIME, "de_DE.UTF-8");
?>

21
var/20_img.php Normal file
View File

@ -0,0 +1,21 @@
<?php #res/img.php
$images = array(
"add" => "res/add.png",
"cancel" => "res/cancel.png",
"check" => "res/check.png",
"delete" => "res/delete.png",
"edit" => "res/edit.png",
"info" => "res/information.png",
"list" => "res/list.png",
"loading" => "res/loading.gif",
"preview" => "res/preview.png",
"print" => "res/print.png",
"refresh" => "res/refresh.png",
"save" => "res/save.png",
"sort_asc" => "res/sort_asc.png",
"sort_desc" => "res/sort_desc.png",
"uncheck" => "res/uncheck.png"
);
?>

28
var/30_errors.php Normal file
View File

@ -0,0 +1,28 @@
<?php #var/errors.php
//Define Level of internal error reporting
//0: none, 1: report in output, 2: report to file (log/errors.txt), 4: just count, 8: only if admin, 16: only if param
//Sums are possible (e.g. 3 means reporting both to file and output
define("DEBUGLVL", 1);
define("ERRORLVL", E_ALL);
define("TPLERRORS", "res/errors.html");
$err = array(
"out" => array(),
"unknown" => "Unbekannter Fehler oder Meldung: ",
"pgsInc" => "Can't include page: ",
"noLib" => "Required library doesn't exist: ",
"noTpl" => "Can't find Template: ",
"noCss" => "Can't find CSS-file: ",
"noJs" => "Can't find JS-file: ",
"invBlogID" => "This is not a valid Blog-ID: ",
"pgsDown" => "Page down for maintenance!",
"passChangeFail" => "Passwort konnte nicht geändert werden: ",
"passChangeSuccess" => "Change password successful: ",
"Mysql" => "Mysql error: ",
"eMail" => "eMail error: ",
"loginFailed" => "Login fehlgeschlagen: ",
"debug" => "Debug-Ausgabe: "
);
?>

9
var/40_lang.php Normal file
View File

@ -0,0 +1,9 @@
<?php #var/40_lang.php
//
$lang = array(
"###ADDRESS.DICH###" => array("Dich", "Euch"),
"###ADDRESS.DEINE###" => array("Deine", "Eure")
);
?>

10
var/50_pages.php Normal file
View File

@ -0,0 +1,10 @@
<?php #var/pages.php
/*$pages[] = pgsCrtPage("Admin", "?main=adm", "nav hidden", "");
$pages[] = pgsCrtPage("Blog", "?main=blog", "nav", "");
$pages[] = pgsCrtPage("Projekte", "?main=projekte", "nav", "");
$pages[] = pgsCrtPage("Webdesign", "?main=webdesign", "nav", "");
$pages[] = pgsCrtPage("Links", "?main=links", "nav", "");
$pages[] = pgsCrtPage("Kontakt", "?main=kontakt", "nav", "");*/
?>

11
var/60_times.php Normal file
View File

@ -0,0 +1,11 @@
<?php #var/times.php
//Date and Time formats
define("FORMATDATE", "d.m.Y");
define("FORMATTIME", "H:i");
$times = array(
"default" => "d.m.Y H:i"
);
?>

18
var/70_mail.php.dist Normal file
View File

@ -0,0 +1,18 @@
<?php #var/70_mail.php
define("MAILNOREPLY", "");
$mail = new PHPMailer\PHPMailer\PHPMailer();
//Server settings
$mail->SMTPDebug = 0; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = ''; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = ''; // SMTP username
$mail->Password = ''; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
?>