Compare commits

...
Author SHA1 Message Date
Bruno Eckhardt de85f80541 hotfixes 2026-05-21 16:45:18 +02:00
Bruno Eckhardt 165b1637da changes 2026-05-21 14:35:27 +02:00
Bruno Eckhardt 5d249b3929 another fix 2026-05-21 14:20:49 +02:00
Bruno Eckhardt 327f650f58 fixes 2026-05-21 14:17:19 +02:00
Bruno Eckhardt d65b778215 new things 2026-05-21 14:13:05 +02:00
Bruno Eckhardt 14d78b548c changes 2026-05-21 13:38:28 +02:00
Bruno Eckhardt 3a86acc057 new 2026-05-21 13:38:18 +02:00
Bruno Eckhardt d24a674643 fix 2026-05-21 13:07:09 +02:00
Bruno Eckhardt 80b31284ab mvc guide, its also in flatnotes under Backend MVC 2026-05-21 13:06:24 +02:00
Bruno Eckhardt f61d0ea8fe create view and controller. USAGE php create_module.php NAME 2026-05-21 13:05:59 +02:00
Bruno Eckhardt b1de4c08f0 new ai generated mvc logic 2026-05-21 12:57:29 +02:00
Bruno Eckhardt 9c6629a61e new structure 2026-05-21 11:42:46 +02:00
Bruno Eckhardt f545c58456 new method formatjson 2026-05-20 15:54:34 +02:00
Bruno Eckhardt 2901a5e362 add create and save new api token 2026-05-20 12:31:20 +02:00
Tower 2231d65465 fixed user_rights control, when new service is created rights are setted for bruno 2026-05-19 21:55:55 +02:00
Tower 4558a717fa new rightscontroller for new service creating 2026-05-19 21:55:14 +02:00
Bruno Eckhardt b2b4ac2124 new endpoint for workreports and moved reports to schoolreports 2026-05-19 15:13:53 +02:00
Bruno Eckhardt f7fd4ed183 request saves 2026-05-19 10:37:45 +02:00
Bruno Eckhardt a73b2ec13f fixes and new api entpoints for lessons and reports 2026-05-19 10:10:43 +02:00
Bruno Eckhardt dce0a0caed htaccess 2026-05-19 07:17:17 +02:00
Bruno Eckhardt 3d8c4291be fix error msg 2026-05-11 14:16:41 +02:00
Bruno Eckhardt a0afeabb27 maybe hotfix 2026-05-11 13:18:05 +02:00
Bruno Eckhardt 96c27a8722 changes 2026-05-11 13:14:16 +02:00
Bruno Eckhardt 4478f7e82f error logging 2026-05-11 13:09:04 +02:00
Bruno Eckhardt c1f3c3ea4e new function get berufsschulberichte 2026-05-11 12:54:37 +02:00
Bruno Eckhardt 2a8564d3bf caching for api 2026-05-11 12:53:15 +02:00
Tower 14f4143207 fix 2026-04-10 21:43:17 +02:00
Tower 53b4bd3423 fixes 2026-04-08 16:53:49 +02:00
Bruno Eckhardt 386bef9094 refresh fixes 2026-04-08 16:34:06 +02:00
Bruno Eckhardt 4e52aa468f fix: minus temperaturen 2026-03-27 06:50:19 +01:00
Bruno Eckhardt f4b65903f7 store error mails in Mailing Table 2026-03-26 08:10:57 +01:00
Bruno Eckhardt 29a1be5d22 enable and disable error logging in errorMailing 2026-03-26 07:52:59 +01:00
Bruno Eckhardt 51bc1f7876 home info htmlspecialchars and right fixes 2026-03-25 08:46:38 +01:00
Bruno Eckhardt 4e0fcfea3f dark and white mode for dropdown 2026-03-25 07:45:24 +01:00
Bruno Eckhardt 63373ac90c dropdown 2026-03-25 07:45:03 +01:00
Bruno Eckhardt 966ed2690c new: auf und abbau von stunden möglich 2026-03-25 07:28:36 +01:00
Bruno Eckhardt 51ce63b0f0 logging error mailing 2026-03-23 15:45:10 +01:00
Bruno Eckhardt d9f98176c5 login as guest 2026-03-23 10:35:46 +01:00
Bruno Eckhardt 2aa48a2601 fixes 2026-03-23 08:37:43 +01:00
Bruno Eckhardt 2bd315efcd feat: api error mailing 2026-03-23 08:18:04 +01:00
Bruno Eckhardt d862ed1102 login tester for mailing 2026-03-23 08:17:02 +01:00
Bruno Eckhardt 5cc4fd0d10 fix 2026-03-16 15:07:44 +01:00
Bruno Eckhardt 24cb1be31f just a test 2026-03-16 13:25:30 +01:00
Bruno Eckhardt 955744ee7e hotfix 2026-03-16 13:22:42 +01:00
Bruno Eckhardt 88f01fe156 update: error mailing 2026-03-16 13:14:32 +01:00
Tower 0c189487c6 more spelling fixes 2026-03-15 21:13:07 +01:00
Tower 50934501ab spelling fixes 2026-03-15 17:46:45 +01:00
Tower 54c77e4651 online bruno can change overtime 2026-03-15 17:41:47 +01:00
Tower 351ec88131 updated config 2026-03-15 17:41:23 +01:00
Tower 7ac6a3cd49 update 2026-03-15 17:41:09 +01:00
Tower 236fe1fd7f new user right system 2026-03-15 17:40:59 +01:00
Tower 4b30f00872 update: client ip logging when mail 2026-03-15 17:36:47 +01:00
Tower e0a4f9ff77 update 2026-03-15 12:32:19 +01:00
Tower ae5beb7ff3 new: print berichte 2026-03-15 12:31:12 +01:00
Bruno Eckhardt 614531394d test 2026-03-13 13:31:26 +01:00
Bruno Eckhardt 773d48f6dd fix: error mailing 2026-03-13 13:12:49 +01:00
Bruno Eckhardt b98c8f39d7 update: enable or disable logging when mail sending 2026-03-13 12:59:35 +01:00
Bruno Eckhardt c286ec3aa2 hopefully fixed use 2026-03-13 12:22:26 +01:00
Bruno Eckhardt 05086a12f5 update: error mailing when cannot connect to DB 2026-03-13 12:19:01 +01:00
Bruno Eckhardt 9f76387eec update: new rows and data 2026-03-13 12:18:40 +01:00
Bruno Eckhardt d2e076e683 fix: wrong var name 2026-03-13 11:30:13 +01:00
Bruno Eckhardt 80184ed2f0 fixes 2026-03-13 11:29:01 +01:00
Bruno Eckhardt 8e2270c674 hotfix 2026-03-13 11:01:13 +01:00
Bruno Eckhardt 53eb3d4bc2 feature: Mailing 2026-03-13 10:35:29 +01:00
Bruno Eckhardt 527e783c75 new scrollbar 2026-03-10 12:17:37 +01:00
Tower 6bcdf3f9e3 feature: scrollable services 2026-03-09 22:29:03 +01:00
Tower e58bfb6bb1 new: domain administration 2026-03-09 22:23:46 +01:00
Tower fc665213b3 new config 2026-03-09 22:06:51 +01:00
Tower d9ae978837 fix: weather sql query and remove htmlspecialchars 2026-03-09 22:02:22 +01:00
Tower 0559317875 update: new berichte 2026-03-09 22:01:54 +01:00
Tower 865320a75c deleting old things 2026-03-09 22:01:14 +01:00
Bruno Eckhardt 35dcb96e5d fix: database connections 2026-03-09 12:49:53 +01:00
Bruno 037396fec0 api hotfix logging; 2026-03-03 10:10:21 +01:00
Bruno d916632d1b new table service 2026-03-02 11:49:41 +01:00
Tower 182997b3fb hotfix and closoed groups 2026-03-01 20:14:49 +01:00
Tower 306e3b9c28 fixes and new api tester service 2026-03-01 19:37:27 +01:00
Tower 24a36b020d fix 2026-02-27 16:48:41 +01:00
Tower e3dae4c853 fix 2026-02-27 15:28:23 +01:00
Tower 66fd469c3a add htaccess but new dockerfile needed 2026-02-27 15:25:42 +01:00
Tower 0846dea367 update: api tests 2026-02-27 15:15:36 +01:00
Tower 2511b94616 test 2026-02-23 21:33:31 +01:00
Tower d1f77a92c5 update: command for weather logging 2026-02-23 16:51:25 +01:00
Tower a81c3adb10 update 2026-02-22 13:31:55 +01:00
Tower 5d98a44731 fix: dynamic title 2026-02-22 13:31:46 +01:00
Tower 7b4ed79e24 fix: new service data_info 2026-02-22 13:31:30 +01:00
Tower 1ee44f37ed fix: more data 2026-02-22 13:31:07 +01:00
Tower fc85cab7d4 fix: new database 2026-02-22 13:30:55 +01:00
Tower 34364f1af6 fix: sql querys 2026-02-22 13:30:21 +01:00
Tower 3bcbadf421 update: Dark / Light mode Button text change and function toggle sitebar groups fixed 2026-02-21 12:42:40 +01:00
Tower f69f141aee hotfix: server node 2026-02-20 21:52:22 +01:00
Tower e035a8f969 hotfix 2026-02-20 21:48:09 +01:00
Bruno Eckhardt 888776988d update: site and user control logout button 2026-02-20 10:01:06 +01:00
Bruno Eckhardt 49c39b532e update: variable control service 2026-02-20 09:28:41 +01:00
Bruno Eckhardt 3f94566d06 hotfix 2026-02-20 07:37:17 +01:00
Tower 316d378670 uodate: Logging variables 2026-02-20 07:31:54 +01:00
Bruno Eckhardt 81ce1edd36 update: delete user in user control 2026-02-19 16:05:03 +01:00
Bruno Eckhardt 320420a4ce update: login 2026-02-19 15:32:50 +01:00
Bruno Eckhardt 4c560a7a10 update: new logout button 2026-02-19 15:14:00 +01:00
Bruno Eckhardt 654d87b297 hotfix 2026-02-19 14:38:48 +01:00
Bruno Eckhardt 223c571608 update 2026-02-19 11:23:19 +01:00
Bruno Eckhardt 3583170c9f new: user control and style fixes 2026-02-19 10:45:21 +01:00
Bruno Eckhardt 3e694a5320 hotfix geoip 2026-02-19 08:40:50 +01:00
Bruno Eckhardt fc942e77fe update: better dark / white mode 2026-02-19 08:36:29 +01:00
Bruno Eckhardt d661800d1f update: new service for generate work-reports 2026-02-18 10:45:49 +01:00
Bruno Eckhardt 1b73c96d70 favicon 2026-02-17 13:07:00 +01:00
Bruno Eckhardt e2ed253eec hotfix 2026-02-17 13:05:20 +01:00
Bruno Eckhardt fb8acbb749 update 2026-02-16 16:37:54 +01:00
Bruno Eckhardt 0fcfb816db test 2026-02-16 14:50:41 +01:00
Bruno Eckhardt a6072865a8 update: style and logging 2026-02-16 14:36:01 +01:00
Bruno Eckhardt 9a72c7e172 update 2026-02-16 13:09:38 +01:00
Bruno Eckhardt 118b651b71 hotfix 2026-02-16 11:07:15 +01:00
Bruno Eckhardt f5f8c7105c hotfix 2026-02-16 11:05:44 +01:00
Bruno Eckhardt b004fcaf40 update: new services and LogController 2026-02-16 11:04:23 +01:00
Bruno Eckhardt 466af07095 hotfix 2026-02-16 10:24:24 +01:00
Bruno Eckhardt 27a6a4bf7c fixes 2026-02-16 09:51:16 +01:00
Bruno Eckhardt a5fd709a89 update: logging 2026-02-16 09:48:36 +01:00
Bruno Notebook afd3ff1c85 add gitignore for config_backups 2026-02-14 21:29:09 +01:00
Bruno Notebook 144ce42d92 update 2026-02-14 21:27:10 +01:00
Bruno Notebook e8f6af6e93 fixes and updates 2026-02-12 23:42:24 +01:00
Bruno Notebook 6ab4feb050 hotfix 2026-02-12 22:59:00 +01:00
Bruno Notebook 74b3639bf2 hotfix 2026-02-12 21:21:36 +01:00
Bruno Notebook 1b5e1a7a0b update: new service control 2026-02-12 21:01:17 +01:00
Bruno Notebook b55de3e46a update 2026-02-12 20:02:06 +01:00
Bruno Eckhardt abc337db03 hotfix 2026-02-05 15:51:59 +01:00
Bruno Eckhardt c0920febca fix: unused file 2026-02-05 15:40:46 +01:00
Bruno Eckhardt d12d7e237f test 2026-02-05 15:34:21 +01:00
Bruno Eckhardt eebfb9f513 update: admin user with permissions for others 2026-02-05 15:30:14 +01:00
Bruno Eckhardt 73ffffb86d hotfix 2026-02-05 13:08:57 +01:00
Bruno Eckhardt 063db10433 update 2026-02-05 12:57:20 +01:00
Bruno Eckhardt 288509b98d update: superuser login 2026-02-05 12:28:36 +01:00
Bruno Eckhardt e9c4488550 hotfix: sessions 2026-02-05 12:03:37 +01:00
Bruno Eckhardt 1e177f35e8 hotfix: logout 2026-02-05 11:59:00 +01:00
Bruno Eckhardt b7e9ab1c24 fix 2026-02-05 08:16:40 +01:00
Bruno Eckhardt 8946a5f898 update: new service for reports 2026-02-05 08:12:51 +01:00
Bruno Eckhardt 6285c0bd9e fix 2026-02-03 16:23:11 +01:00
Bruno Eckhardt 412aaa4aac Merge branch 'Services'
# Conflicts:
#	WEBROOT/config.php
#	WEBROOT/style.css
2026-02-02 08:55:57 +01:00
Bruno Eckhardt 4182ac998c update 2026-02-02 08:55:19 +01:00
Bruno Eckhardt aab098ff5e update: DB-Login 2026-02-02 08:54:07 +01:00
Bruno Eckhardt 1bf7f87e4f update: chart style 2026-01-27 14:23:41 +01:00
Tower 6a16e9fd0a Merge branch 'login'
# Conflicts:
#	WEBROOT/style.css
2026-01-26 23:08:48 +01:00
Tower 7fc8621fb9 fix style 2026-01-26 23:08:18 +01:00
Tower 69d8266903 styling 2026-01-26 23:00:47 +01:00
Tower be843b9365 Merge branch 'Config' 2026-01-26 22:59:30 +01:00
Tower cfddbde9f4 Merge branch 'login' 2026-01-26 22:59:22 +01:00
Tower 65ec3adb5a Merge branch 'Services' 2026-01-26 22:59:19 +01:00
Tower b16f696e0a fix and update 2026-01-26 22:59:08 +01:00
Tower ebd93db8b2 update: login / logout 2026-01-26 22:58:23 +01:00
Tower 6efcf548d5 new: home 2026-01-26 22:57:25 +01:00
129 changed files with 11690 additions and 879 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
WEBROOT/config_backups/*
WEBROOT/static/*
WEBROOT/sitemap.xml
+7 -1
View File
@@ -5,12 +5,18 @@
}
],
"settings": {
"workbench.colorTheme": "Default Dark Modern",
"workbench.colorTheme": "Dark Modern",
"workbench.colorCustomizations": {
"activityBar.background": "#ff000075",
"activityBar.foreground": "#000000",
"breadcrumb.foreground": "#FFFFFF",
},
"files.exclude": {
"*.git*": true,
"WEBROOT/config_backups": true,
"WEBROOT/static": true,
"WEBROOT/templates": true,
},
"editor.renderWhitespace": "all",
"editor.smoothScrolling": true,
"editor.fontSize": 14,
-73
View File
@@ -1,73 +0,0 @@
#!/bin/bash
while true; do
echo ""
echo "============================="
echo " Git Management Script"
echo "============================="
echo ""
echo "1) Geänderte Dateien anzeigen"
echo "2) Einzelne Dateien zum Commit auswählen"
echo "3) Alles stagen"
echo "4) Commit & Push"
echo "5) Alte Stände anzeigen"
echo "6) Aktueller Branch"
echo "7) Änderungen"
echo "99) Programm beenden"
echo ""
read -p "Auswahl: " auswahl
case $auswahl in
1)
echo "Geänderte Dateien:"
git status -s
;;
2)
echo "Geänderte Dateien:"
git status -s
echo ""
read -p "Welche Datei soll gestaged werden? (Pfad eingeben): " file
git add "$file"
echo ">> Datei '$file' wurde gestaged."
;;
3)
echo ">> Alle Dateien werden gestaged..."
git add -A
;;
4)
read -p "Commit Nachricht: " commitmsg
git commit -m "$commitmsg"
echo ">> Pushen..."
git push
;;
5)
echo ">> Alte Commits:"
git log --oneline --graph --decorate --all
;;
6)
echo "Aktueller Branch"
git branch
;;
7)
echo "Änderungen"
git status
;;
99)
echo "Beendet."
exit 0
;;
*)
echo "Ungültige Auswahl!"
;;
esac
done
+166
View File
@@ -0,0 +1,166 @@
# 🏗️ Backend MVC Framework - Das Handbuch
Dieses Framework ist eine performante, leichtgewichtige und modulare PHP-Architektur, die speziell für die Entwicklung von professionellen Backends und Dashboards entwickelt wurde. Es implementiert das **Model-View-Controller (MVC)** Pattern und trennt strikt zwischen Datenlogik, Geschäftslogik und UI-Design.
---
## 🏛️ 1. Architektur & Verzeichnisstruktur
Das Herzstück des Frameworks liegt in `WEBROOT/src/MVC/`. Die Struktur ist darauf ausgelegt, dass das Projekt beliebig wachsen kann, ohne unübersichtlich zu werden.
### 📂 Ordner-Struktur im Detail
* **`WEBROOT/index.php`**: Der zentrale Einstiegspunkt (Front Controller). Jede Anfrage läuft hier auf. Hier werden Routen registriert und das Layout zusammengesetzt.
* **`src/MVC/Core/`**:
* `Controller.php`: Basisklasse für alle Controller. Bietet Methoden für Rendering und JSON-Output.
* `Model.php`: Basisklasse für Datenbankzugriffe. Implementiert sichere CRUD-Methoden via Prepared Statements.
* `View.php`: Die Engine, die Daten in HTML-Templates extrahiert.
* `Router.php`: Verwaltet Routen und schaltet Middlewares (Auth/Admin) vor.
* `Layout/Layout.php`: Das Block-System für modulares UI-Design.
* **`src/MVC/Controller/`**: Hier landen deine PHP-Klassen für die Logik. Beispiel: `UserController.php`, `LogController.php`.
* **`src/MVC/Model/`**: Jede Klasse entspricht einer Datenbanktabelle. Hier wird definiert, *wie* Daten geholt oder gespeichert werden.
* **`src/MVC/View/`**: Reine HTML-Dateien mit minimalem PHP-Code für die Anzeige.
* **`src/MVC/Layout/Templates/`**: Enthält das Grundgerüst (`main.php`), in das die Views eingebettet werden.
---
## 🚦 2. Der Request-Lifecycle (Wie eine Seite entsteht)
1. Ein Benutzer ruft `?service=benutzer` auf.
2. Die `index.php` lädt den **Autoloader** und initialisiert den **Router**.
3. Der **Router** prüft, ob eine Middleware (z.B. `auth`) für diesen Service konfiguriert ist.
4. Wenn der Zugriff erlaubt ist, erstellt der Router eine Instanz des jeweiligen **Controllers** und ruft die Zielmethode auf.
5. Der **Controller** nutzt ein **Model**, um Daten aus der Datenbank zu holen.
6. Der Controller übergibt diese Daten an eine **View** (`$this->render()`).
7. Die **index.php** nimmt das HTML der View entgegen, packt es in den `content`-Block des **Layouts** und gibt die fertige Seite aus.
---
## 🏛️ 3. Arbeiten mit dem Model-Layer (Datenbank)
Vermeide SQL direkt im Controller! Nutze immer Models für eine saubere Abstraktion.
### Beispiel: Ein eigenes Model erstellen
```php
namespace MVC\Model;
use MVC\Core\Model;
class Product extends Model {
protected static $table = "Produkte"; // Tabellenname in der DB
public static function getExpensiveProducts() {
return self::where("PREIS > ?", 100); // Sicher gegen SQL-Injection!
}
}
```
### Verfügbare Methoden der Basisklasse:
* `all()`: Lädt alles aus der Tabelle.
* `find($id)`: Findet einen Datensatz per ID.
* `where($sql, ...$params)`: Filtert mit Prepared Statements.
* `insert($array)`: Speichert neue Daten (z.B. `['TITEL' => 'Test']`).
* `update($array, $where, ...$params)`: Aktualisiert bestehende Daten.
* `delete($where, ...$params)`: Löscht Datensätze sicher.
---
## 🎮 4. Controller & Formularverarbeitung
Controller steuern den Ablauf. Sie entscheiden, was bei `GET` und was bei `POST` passiert.
### Beispiel: Daten verarbeiten
```php
public function save() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Daten via Model speichern
User::update(['STATUS' => 'aktiv'], "ID = ?", $_POST['id']);
// WICHTIG: Danach immer Redirect (Post-Redirect-Get Pattern)
header("Location: ?service=user_list");
exit;
}
return $this->render('edit_view');
}
```
---
## 🧱 5. Das modulare Block-Layout
Das Layout-System ermöglicht es, verschiedene Teile der Seite (Header, Sidebar, Content) unabhängig voneinander zu befüllen.
### Blöcke in `index.php` befüllen:
```php
$layout = new \MVC\Layout\Layout('main');
$layout->setBlock('title', 'Admin Dashboard');
$layout->setBlock('sidebar', $sidebarHtml);
$layout->setBlock('content', $controllerOutput);
```
### Blöcke im Template (`main.php`) ausgeben:
```html
<aside class="sidebar">
<?= $this->getBlock('sidebar') ?>
</aside>
```
---
## 🚀 6. CLI-Werkzeuge für Entwickler
Das Framework kommt mit automatisierten Scripten, um lästige Routinearbeiten zu vermeiden.
### Projekt initialisieren
Erstellt ein komplettes Skelett inkl. Dev-Server und API.
```bash
php init_mvc.php MeinProjekt
```
### Modul (Controller + View) erstellen
Erstellt zwei Dateien und gibt dir den Code für den Router aus.
```bash
php create_module.php kunden_verwaltung
```
### Model erstellen
Erstellt eine Model-Klasse mit Tabellenzuweisung und dokumentierten Spalten.
```bash
php create_model.php Kunden ID,NAME,EMAIL,TELEFON
```
---
## 🛡️ 7. Sicherheit & Best Practices
1. **XSS-Schutz**: Gib niemals Variablen direkt in der View aus. Nutze immer `<?= htmlspecialchars($var) ?>`.
2. **SQL-Injection**: Nutze niemals Variablen direkt in einem SQL-String. Nutze die Methoden `where()`, `update()` etc. des Models. Sie verwenden intern Prepared Statements.
3. **Namespaces**: Alle Klassen im `src/MVC` Ordner nutzen Namespaces. Achte beim Aufruf globaler Klassen (außerhalb des MVC-Ordners) auf den führenden Backslash, z.B. `\db_connect()`.
4. **Error Handling**: Fehler werden zentral in der `index.php` gefangen. Admins erhalten detaillierte Informationen, User sehen eine sichere Fehlermeldung.
---
## ⚡ 8. AJAX & API Entwicklung
Um Daten ohne Seiten-Reload zu laden, bietet der Controller die `json()` Methode:
```php
public function getStatus() {
$data = ['online' => true, 'time' => date('H:i')];
return $this->json($data); // Setzt Header und beendet Script
}
```
In deinem JavaScript kannst du dies dann einfach per `fetch()` abrufen.
---
## 🛠️ 9. Installation & Start
1. Stelle sicher, dass PHP 8.x installiert ist.
2. Passe die `src/config/env.ini` mit deinen Datenbankdaten an.
3. Starte den internen Server: `php server.php`.
4. Öffne `http://localhost:8000` im Browser.
---
*Dieses Framework wurde für maximale Produktivität entwickelt. Bei Fragen schau in die integrierte Dokumentation im Backend.*
+19
View File
@@ -0,0 +1,19 @@
RewriteEngine On
RewriteRule ^(Commands|config_backups|controller|modules)($|/.*) - [F,L,NC]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# -----------------------------------
# .php entfernen
# -----------------------------------
# browser requestet datei.php -> redirect zu /datei
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,L]
# /datei -> datei.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+)$ $1.php [L]
+54
View File
@@ -0,0 +1,54 @@
<?php
// loginTest.php
$loginUrl = "https://backend.blackpi.ipv64.net/login.php"; // URL zu deinem Login-Script
// Testfälle
$tests = [
[
'username' => 'Bruno', // korrektes Testkonto
'password' => 'bBHofurUJWKzPE8Z', // korrektes Passwort
'expected' => true,
'description' => 'Erfolgreiches Login'
],
[
'username' => 'admin',
'password' => 'falschespasswort',
'expected' => false,
'description' => 'Fehlerhaftes Login'
]
];
foreach ($tests as $test) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $loginUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'username' => $test['username'],
'password' => $test['password']
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // Wichtige Info: redirect erkennen
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($response, $headerSize);
curl_close($ch);
// Prüfen, ob Login erfolgreich war: Redirect auf index.php oder Session gesetzt
if (strpos($response, "Location: index.php") !== false || strpos($body, "Login fehlgeschlagen") === false) {
$success = true;
} else {
$success = false;
}
if ($success === $test['expected']) {
echo "[PASS] {$test['description']}\n";
} else {
echo "[FAIL] {$test['description']}\n";
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
include_once( __DIR__ . '/../src/utils/databaseMethods.php');
include_once( __DIR__ . '/../src/classes/getData.php');
include_once( __DIR__ . '/../src/database/databaseConnect.php');
$data = new getSpecificData();
print_r($data->getWeather());
echo "";
$aktuell=($data->getWeather()['aktuell']);
$min=($data->getWeather()['min']);
$max=($data->getWeather()['max']);
$gefuehlt=($data->getWeather()['gefuehlt']);
$zeit=(date("d.m.Y H:i:s"));
DatabaseInsert(
"Wetter",
"ZEIT, AKTUELL, MIN, MAX, GEFUEHLT",
$zeit,
$aktuell,
$min,
$max,
$gefuehlt,
);
+101
View File
@@ -0,0 +1,101 @@
<?php
include_once( __DIR__ . '/../../src/utils/databaseMethods.php');
include_once( __DIR__ . '/../../src/classes/getData.php');
include_once( __DIR__ . '/../../src/controller/apiController.php');
include_once( __DIR__ . '/../../src/utils/mailer.php');
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Authorization, Function, Content-Type");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
$validTokens = DatabaseShow(
"API_Credentials",
"TOKEN"
);
$validTokens = array_column($validTokens, 'TOKEN');
$headers = getallheaders();
$token = $headers['Authorization'] ?? $headers['authorization'] ?? $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$function = $headers['Function'] ?? $headers['function'] ?? '';
if (!in_array($token, $validTokens)) {
http_response_code(401);
$error = json_encode([
"error" => "Unauthorized",
"debug_received_token" => $token,
"debug_all_headers" => $headers
]);
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function,
$error
);
errorMail(
"API Login failed",
$error,
true,
);
echo json_encode(
[
"error" => "Unauthorized",
"Contact" => "bruno.eckhardt07@gmail.com",
]
);
exit;
}
$data = null;
if (in_array($token, $validTokens)) {
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function
);
if ($function === "IPs") {
$data = DatabaseShow(
"logs",
"CLIENT_IP"
);
}
if ($function === "Ueberstunden") {
$data = DatabaseShow(
"Ueberstunden",
"MINUTEN"
);
}
if ($function === "Berichte") {
$data = DatabaseShowWithFK(
"Berufsschulberichte",
$Berufsschulberichte,
);
}
echo json_encode(
[
"success" => true,
"data" => $data,
]
);
exit;
}
+113
View File
@@ -0,0 +1,113 @@
<?php
include_once( __DIR__ . '/../../src/utils/databaseMethods.php');
include_once( __DIR__ . '/../../src/classes/getData.php');
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Authorization, Function, Content-Type");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
$validTokens = [
"15a437d128c918633e57dc7d18118a073b807644f21731ed5a7ebcf3eca9e242",
];
$baseUploadDir = __DIR__ . "/../services/uploads/";
$headers = getallheaders();
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$token = trim($token);
if (!in_array($token, $validTokens, true)) {
http_response_code(401);
echo json_encode([
"error" => "Unauthorized",
"received_token" => $token
]);
exit;
}
if (!isset($_FILES['files'])) {
http_response_code(400);
echo json_encode(["error" => "No files uploaded"]);
exit;
}
$folderName = null;
$readmeContent = null;
// Prüfen ob readme.md hochgeladen wurde
foreach ($_FILES['files']['name'] as $key => $name) {
if (strtolower($name) === "readme.md") {
$tmpName = $_FILES['files']['tmp_name'][$key];
$readmeContent = file_get_contents($tmpName);
break;
}
}
if ($readmeContent) {
// Erste Markdown-Überschrift extrahieren (# Titel)
if (preg_match('/^#\s*(.+)$/m', $readmeContent, $matches)) {
$rawName = $matches[1];
// Slug erzeugen (ordner-tauglich machen)
$folderName = strtolower($rawName);
$folderName = preg_replace("/[^a-z0-9]+/", "-", $folderName);
$folderName = trim($folderName, "-");
}
}
// Fallback falls keine readme oder kein Titel
if (!$folderName) {
$folderName = uniqid("upload_", true);
}
$uploadDir = $baseUploadDir . $folderName . "/";
if (!mkdir($uploadDir, 0755, true)) {
http_response_code(500);
echo json_encode(["error" => "Failed to create directory"]);
exit;
}
$uploadedFiles = [];
foreach ($_FILES['files']['tmp_name'] as $key => $tmpName) {
if ($_FILES['files']['error'][$key] !== UPLOAD_ERR_OK) {
continue;
}
$originalName = basename($_FILES['files']['name'][$key]);
$safeName = preg_replace("/[^a-zA-Z0-9._-]/", "", $originalName);
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($tmpName);
if ($_FILES['files']['size'][$key] > 25 * 1024 * 1024) {
continue;
}
$targetPath = $uploadDir . $safeName;
if (move_uploaded_file($tmpName, $targetPath)) {
$uploadedFiles[] = $safeName;
}
}
$json = json_encode([
"success" => true,
"folder" => $folderName,
"uploaded_files" => $uploadedFiles
]);
DatabaseInsert(
"API",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
"Upload",
$json
);
echo $json;
+37
View File
@@ -0,0 +1,37 @@
<?php
include_once( __DIR__ . '/../../src/utils/databaseMethods.php');
include_once( __DIR__ . '/../../src/classes/getData.php');
include_once(__DIR__ . '/../../src/controller/apiController.php');
header('Content-Type: application/json');
$api = (new ApiController());
if ($api->urlAuth($_GET['token']) == true ) {
if (isset($_GET['day'])) {
$day = $_GET['day'];
$data = DatabaseShowWithFK(
"Stundenplan",
$Stundenplan,
"ZEITEN, $day",
"$day IS NOT NULL AND $day != '' AND $day != '(NULL)' ORDER BY ZEITEN ASC"
);
} else {
$data = DatabaseShowWithFK(
"Stundenplan",
$Stundenplan,
"ZEITEN, MO, DI, MO, DO, FR",
);
}
echo $api->jsonSuccess($data);
$api->requestSave();
}
/**
* http://localhost:9000/api/v2/lessons.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3
* http://localhost:9000/api/v2/lessons.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3&day=FR
*/
+37
View File
@@ -0,0 +1,37 @@
<?php
include_once( __DIR__ . '/../../src/utils/databaseMethods.php');
include_once( __DIR__ . '/../../src/classes/getData.php');
include_once(__DIR__ . '/../../src/controller/apiController.php');
header('Content-Type: application/json');
$api = (new ApiController());
if ($api->urlAuth($_GET['token']) == true ) {
if (isset($_GET['date'])) {
$date = $_GET['date'];
$data = DatabaseShowWithFK(
"Berufsschulberichte",
$Berufsschulberichte,
"*",
"DATUM = ?",
$date
);
} else {
$data = DatabaseShowWithFK(
"Berufsschulberichte",
$Berufsschulberichte,
);
}
echo $api->jsonSuccess($data);
$api->requestSave();
}
/**
* http://localhost:9000/api/v2/schoolReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3
* http://localhost:9000/api/v2/schoolReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3&date=2025-09-09
*/
+37
View File
@@ -0,0 +1,37 @@
<?php
include_once( __DIR__ . '/../../src/utils/databaseMethods.php');
include_once( __DIR__ . '/../../src/utils/requestLogger.php');
include_once( __DIR__ . '/../../src/classes/getData.php');
include_once(__DIR__ . '/../../src/controller/apiController.php');
header('Content-Type: application/json');
$api = (new ApiController());
if ($api->urlAuth($_GET['token']) == true ) {
if (isset($_GET['date'])) {
$date = $_GET['date'];
$data = DatabaseShow(
"Firmenberichte",
"DATUM, PROZESS_1, PROZESS_2, PROZESS_3, PROZESS_4, BEGINN, ENDE_PUBLIC",
"DATUM = ?",
$date
);
} else {
$data = DatabaseShow(
"Firmenberichte",
"DATUM, PROZESS_1, PROZESS_2, PROZESS_3, PROZESS_4, BEGINN, ENDE_PUBLIC",
);
}
echo $api->jsonSuccess($data);
$api->requestSave();
}
/**
* http://localhost:9000/api/v2/workReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3
* http://localhost:9000/api/v2/workReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3&date=2025-09-09
*/
+388 -38
View File
@@ -1,47 +1,397 @@
<?php
$serviceGroups = [
'Info' => [
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' => [
'home_info'
]
],
'Logs' => [
'label' => 'Webserver Logs',
'services' =>
array (
0 => 'home_info',
1 => 'links',
3 => 'documentation',
),
),
'Ausbildung' =>
array (
'label' => 'Ausbildung',
'defaultOpen' => true,
'services' => [
'request_logs',
'request_chart'
]
],
'System' => [
'label' => 'Administration',
'services' =>
array (
0 => 'print_static',
1 => 'zeiterfassung',
2 => 'berichte_arbeit_gen',
3 => 'berichte',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' => [
'services_control'
]
],
];
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Verwaltung',
'defaultOpen' => false,
'services' =>
array (
0 => 'data_info',
1 => 'services_control',
2 => 'user_control',
3 => 'variablen_control',
),
),
'Test' =>
array (
'label' => 'Dev / Test',
'defaultOpen' => false,
'services' =>
array (
0 => 'api_tester',
1 => 'weather_chart',
2 => 'tabellen',
3 => 'domains',
),
),
);
$services = [
'home_info' => [
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true
],
'request_logs' => [
'name' => 'Request Logs',
'active' => true
],
'request_chart' => [
'name' => 'Request Statisktik',
'active' => true
],
'services_control' => [
'name' => 'Site Control',
'active' => true
],
];
'active' => true,
'adminOnly' => false,
),
'print_static' =>
array (
'name' => 'Berichte Drucken',
'active' => true,
'adminOnly' => false,
),
'api_tester' =>
array (
'name' => 'API Testing',
'active' => true,
'adminOnly' => true,
),
'weather_chart' =>
array (
'name' => 'Wetter Statistik',
'active' => true,
'adminOnly' => true,
),
'data_info' =>
array (
'name' => 'Data Info',
'active' => true,
'adminOnly' => true,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => true,
),
'services_control' =>
array (
'name' => 'Seiten',
'active' => true,
'adminOnly' => true,
),
'zeiterfassung' =>
array (
'name' => 'Zeit Erfassung',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit_gen' =>
array (
'name' => 'Berichte PDF',
'active' => true,
'adminOnly' => false,
),
'user_control' =>
array (
'name' => 'Benutzer',
'active' => true,
'adminOnly' => true,
),
'variablen_control' =>
array (
'name' => 'Variablen',
'active' => true,
'adminOnly' => true,
),
'tabellen' =>
array (
'name' => 'Tabellen',
'active' => true,
'adminOnly' => true,
),
'berichte' =>
array (
'name' => 'Berichte Einsehen',
'active' => true,
'adminOnly' => false,
),
'domains' =>
array (
'name' => 'Domains',
'active' => true,
'adminOnly' => false,
),
'tester' =>
array (
'name' => 'TESTER',
'active' => true,
'adminOnly' => false,
),
'documentation' =>
array (
'name' => 'Dokumentation',
'active' => true,
'adminOnly' => false,
),
'logout' =>
array (
'name' => 'Abmelden',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'IoT',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
?>
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
11 =>
array (
'label' => 'Ender 3 V3 KE',
'url' => 'http://10.233.1.52',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
12 =>
array (
'label' => 'Ubuntu NAS',
'url' => 'http://10.233.1.32:9000',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
13 =>
array (
'label' => 'Backend',
'url' => 'https://backend.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
14 =>
array (
'label' => 'Dev Backend',
'url' => 'https://dev-backend.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
15 =>
array (
'label' => 'Dev Pubic',
'url' => 'https://dev-public.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
16 =>
array (
'label' => 'Local Backend',
'url' => 'http://backend.local.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
17 =>
array (
'label' => 'Local Pubic',
'url' => 'http://public.local.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
18 =>
array (
'label' => 'Proxmox',
'url' => 'https://100.88.208.86:8006',
'newTab' => true,
'adminOnly' => true,
'group' => 'devices',
),
19 =>
array (
'label' => 'Flatnotes',
'url' => 'http://10.233.1.130:8080',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
);
@@ -0,0 +1,113 @@
<?php
$superuser = [
'admin' => [
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
],
];
// Services
$serviceGroups = [
'Info' => [
'label' => 'Home',
'defaultOpen' => true,
'services' => [
'home_info',
'berichte_arbeit',
'links',
]
],
'Logs' => [
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' => [
'request_logs',
'request_chart',
]
],
'System' => [
'label' => 'Administration',
'defaultOpen' => true,
'services' => [
'services_control',
'logout'
]
],
];
$services = [
'home_info' => [
'name' => 'Home',
'active' => true,
'adminOnly' => false
],
'links' => [
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false
],
'request_logs' => [
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false
],
'request_chart' => [
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false
],
'services_control' => [
'name' => 'Site Control',
'active' => true,
'adminOnly' => true
],
'logout' => [
'name' => 'Logout',
'active' => true,
'adminOnly' => false
],
'berichte_arbeit' => [
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false
],
];
// Links
$linkGroups = [
'info' => [
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => true
],
'tools' => [
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => true
],
'admin' => [
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false
],
];
$linkButtons = [
[
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => true,
'group' => 'admin'
],
[
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => true,
'group' => 'admin'
],
];
?>
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => false,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => false,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Zuhause',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Zuhause',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Zuhause',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Zuhause',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,112 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Homeee',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Zuhause',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Request Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Request Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Statisktik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Statistik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,128 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'berichte_arbeit',
2 => 'links',
),
),
'Logs' =>
array (
'label' => 'Webserver Logs',
'defaultOpen' => true,
'services' =>
array (
0 => 'request_logs',
1 => 'request_chart',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => false,
'adminOnly' => false,
),
'request_logs' =>
array (
'name' => 'Logs',
'active' => true,
'adminOnly' => false,
),
'request_chart' =>
array (
'name' => 'Statistik',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,179 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
);
@@ -0,0 +1,195 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
);
@@ -0,0 +1,227 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,227 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'Tools',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
);
@@ -0,0 +1,235 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'IoT',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
11 =>
array (
'label' => 'Ender 3 V3 KE',
'url' => 'http://10.233.1.52',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
);
@@ -0,0 +1,235 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'IoT',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
11 =>
array (
'label' => 'Ender 3 V3 KE',
'url' => 'http://10.233.1.52',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
);
@@ -0,0 +1,257 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
3 => 'berichte_arbeit_gen',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'user_control',
2 => 'logout',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Site Control',
'active' => true,
'adminOnly' => true,
),
'logout' =>
array (
'name' => 'Logout',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit_gen' =>
array (
'name' => 'Arbeitsberichte PDF',
'active' => true,
'adminOnly' => false,
),
'user_control' =>
array (
'name' => 'Benutzerverwaltung',
'active' => true,
'adminOnly' => false,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'IoT',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
11 =>
array (
'label' => 'Ender 3 V3 KE',
'url' => 'http://10.233.1.52',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
12 =>
array (
'label' => 'Ubuntu NAS',
'url' => 'http://10.233.1.32:9000',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
);
@@ -0,0 +1,257 @@
<?php
$superuser = array (
'admin' =>
array (
'password' => 'bBHofurUJWKzPE8Z:',
'active' => true,
),
);
$serviceGroups = array (
'Info' =>
array (
'label' => 'Home',
'defaultOpen' => true,
'services' =>
array (
0 => 'home_info',
1 => 'links',
2 => 'berichte_arbeit',
3 => 'berichte_arbeit_gen',
),
),
'Logs' =>
array (
'label' => 'Webserver',
'defaultOpen' => true,
'services' =>
array (
0 => 'public_request_logs',
1 => 'public_request_chart',
2 => 'backend_request_logs',
3 => 'backend_request_chart',
4 => 'personal_request_logs',
),
),
'System' =>
array (
'label' => 'Administration',
'defaultOpen' => true,
'services' =>
array (
0 => 'services_control',
1 => 'user_control',
2 => 'test',
),
),
);
$services = array (
'home_info' =>
array (
'name' => 'Home',
'active' => true,
'adminOnly' => false,
),
'links' =>
array (
'name' => 'Externe Links',
'active' => true,
'adminOnly' => false,
),
'public_request_logs' =>
array (
'name' => 'Public Logs',
'active' => true,
'adminOnly' => false,
),
'public_request_chart' =>
array (
'name' => 'Public Statistik',
'active' => true,
'adminOnly' => false,
),
'backend_request_logs' =>
array (
'name' => 'Backend Logs',
'active' => true,
'adminOnly' => false,
),
'backend_request_chart' =>
array (
'name' => 'Backend Statistik',
'active' => true,
'adminOnly' => false,
),
'personal_request_logs' =>
array (
'name' => 'Persönliche Logs',
'active' => true,
'adminOnly' => false,
),
'services_control' =>
array (
'name' => 'Seitenverwaltung',
'active' => true,
'adminOnly' => true,
),
'berichte_arbeit' =>
array (
'name' => 'Arbeitsberichte',
'active' => true,
'adminOnly' => false,
),
'berichte_arbeit_gen' =>
array (
'name' => 'Arbeitsberichte PDF',
'active' => true,
'adminOnly' => false,
),
'user_control' =>
array (
'name' => 'Benutzerverwaltung',
'active' => true,
'adminOnly' => false,
),
'test' =>
array (
'name' => 'Test Seite',
'active' => true,
'adminOnly' => true,
),
);
$linkGroups = array (
'info' =>
array (
'label' => 'Informationen',
'color' => '#3498db',
'defaultOpen' => false,
),
'tools' =>
array (
'label' => 'IoT',
'color' => '#2ecc71',
'defaultOpen' => false,
),
'admin' =>
array (
'label' => 'Administration',
'color' => '#e74c3c',
'defaultOpen' => false,
),
'devices' =>
array (
'label' => 'Geräte',
'color' => '#b7db33',
'defaultOpen' => false,
),
);
$linkButtons = array (
0 =>
array (
'label' => 'Gitea',
'url' => 'http://gitea.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
1 =>
array (
'label' => 'HAProxy',
'url' => 'http://stats.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
2 =>
array (
'label' => 'Public',
'url' => 'https://blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'info',
),
3 =>
array (
'label' => 'NAS-1',
'url' => 'http://nas-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
4 =>
array (
'label' => 'NAS-2',
'url' => 'http://nas-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
5 =>
array (
'label' => 'FritzBox-1',
'url' => 'http://fritzbox-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
6 =>
array (
'label' => 'FritzBox-2',
'url' => 'http://fritzbox-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
7 =>
array (
'label' => 'GS1910-24',
'url' => 'http://switch.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
8 =>
array (
'label' => 'NWA5121-NI Innen',
'url' => 'http://ap-1.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
9 =>
array (
'label' => 'NWA5121-NI Aussen',
'url' => 'http://ap-2.blackpi.ipv64.net',
'newTab' => true,
'adminOnly' => false,
'group' => 'devices',
),
10 =>
array (
'label' => 'ZyWALL 110',
'url' => 'http://10.233.1248',
'newTab' => true,
'adminOnly' => false,
'group' => 'admin',
),
11 =>
array (
'label' => 'Ender 3 V3 KE',
'url' => 'http://10.233.1.52',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
12 =>
array (
'label' => 'Ubuntu NAS',
'url' => 'http://10.233.1.32:9000',
'newTab' => true,
'adminOnly' => false,
'group' => 'tools',
),
);
-188
View File
@@ -1,188 +0,0 @@
<?php
class getSpecificData {
public function getUserAgent(): string {
return $_SERVER['HTTP_USER_AGENT'] ?? 'Unbekannt';
}
public function getRequestURL(): string {
return $_SERVER['REQUEST_URI'] ?? 'Unbekannt';
}
public function getCookie(string $name): ?string {
return $_COOKIE[$name] ?? 'Unbekannt';
}
public function getServerCookie(string $name): ?string {
return $_COOKIE[$name] ?? 'Unbekannt';
}
public function getSessionID(): string {
return $session_id ?? 'Unbekannt ';
}
public function getServerPort(): string {
return $_SERVER['SERVER_PORT'] ?? 'Unbekannt';
}
public function getClientPort(): string {
return $_SERVER['REMOTE_PORT'] ?? 'Unbekannt';
}
public function getDocumentRoot(): string {
return $_SERVER['DOCUMENT_ROOT'] ?? 'Unbekannt';
}
public function getQuery(): string {
return $_SERVER['QUERY_STRING'] ?? 'Unbekannt';
}
public function getRequestMethod(): string {
return $_SERVER['REQUEST_METHOD'] ?? 'Unbekannt';
}
public function getCurrentDir(): string {
return __DIR__ ;
}
public function getReferer(): string {
return $_SERVER['HTTP_REFERER'] ?? 'Unbekannt';
}
public function getDatabase(): string {
$conn = db_connect();
return $conn->host_info;
}
public function getServerName(): string {
$Servername = $_SERVER['SERVER_NAME'] ?? 'Unbekannt';
if (in_array($Servername, ['Unbekannt', '0.0.0.0', '127.0.0.1'])) {
return "Lokal";
} else {
return $Servername;
}
}
public function getServerIP(): string {
$ServerIP = $_SERVER['SERVER_ADDR'] ?? 'Unbekannt';
if (in_array($ServerIP, ['Unbekannt', '0.0.0.0', '127.0.0.1'])) {
return "Lokal";
} else {
return $ServerIP;
}
}
public function getClientIP(): string {
$xff = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null;
if ($xff) {
$ips = array_map('trim', explode(',', $xff));
$clientIp = $ips[0];
return $clientIp;
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
public function getRequestTime(): string {
date_default_timezone_set('Europe/Berlin');
$timestamp = $_SERVER['REQUEST_TIME'] ?? time();
return date('Y-m-d H:i:s', $timestamp);
}
function getGeoIP($ClientIP) {
$whitelist = (new getSpecificData())->getWhitelistedIPs();
if (in_array($ClientIP, $whitelist)) {
return "Lokal";
} else {
$response = file_get_contents("http://ip-api.com/json/{$ClientIP}?fields=country,countryCode");
$data = json_decode($response);
return $data->country;
}
}
function getWhitelistedIPs() {
include_once 'DatabaseController.php';
$data = DatabaseShow(
"Whitelisted",
"`IP-ADDRESSE`"
);
$results = [];
foreach ($data as $row) {
$results[] =$row['IP-ADDRESSE'];
}
return $results;
}
function getServerNode($ServerIP) {
$nodes = [
'node1' => '172.30.0.11',
'node2' => '172.30.0.12',
'node3' => '172.30.0.13',
'node4' => '172.30.0.14',
'Lokal' => 'Lokal',
];
foreach ($nodes as $node => $ip) {
if ($ServerIP == $ip) {
return $node;
break;
}
}
}
function getClientStatus($ClientIP) {
if (in_array($ClientIP, $this->getWhitelistedIPs())) {
return "Trusted";
}
return "Untrusted";
}
function test() {
return "TEST";
}
public function getAllData(): array {
return [
'Document-Root' => $this->getDocumentRoot(),
'CurrentDir' => $this->getCurrentDir(),
'Referer' => $this->getReferer(),
'Request URL' => $this->getRequestURL(),
'Server-Port' => $this->getServerPort(),
'Server-IP' => $this->getServerIP(),
'Server-Name' => $this->getServerName(),
'Server-Node' => $this->getServerNode($this->getServerIP()),
'Client-IP' => $this->getClientIP(),
'Client-Port' => $this->getClientPort(),
'Client-Land' => $this->getGeoIP($this->getClientIP()),
'Client-User-Agent' => $this->getUserAgent(),
'Client-Cookie' => $this->getCookie('USER'),
'Client-Server-Cookie' => $this->getCookie('SESSSRV'),
'Client-Session-ID' => $this->getSessionID(),
'Query' => $this->getQuery(),
'Request-Method' => $this->getRequestMethod(),
'Request-Time' => $this->getRequestTime(),
'Database' => $this->getDatabase(),
'Whitelisted Status' => $this->getClientStatus($this->getClientIP()),
'Whitelisted IPs' => $this->getWhitelistedIPs(),
];
}
public function ShowAllData(): void {
$SpecificData = (new getSpecificData())->getAllData();
echo "<pre>";
foreach ($SpecificData as $key => $value) {
if (is_array($value)) {
$value = implode(', ', $value);
}
printf("%-22s : %s\n", $key, $value);
}
echo "</pre>";
}
}
-42
View File
@@ -1,42 +0,0 @@
<?php
function db_connect() {
$servers = [
'dev' => [
'hostaddr' => '10.233.1.29',
'username' => 'worker',
'password' => 'bBHofurUJWKzPE8Z',
'database' => 'DEV',
],
'vpn' => [
'hostaddr' => '100.123.136.86',
'username' => 'worker',
'password' => 'bBHofurUJWKzPE8Z',
'database' => 'DEV',
],
'live' => [
'hostaddr' => '10.233.1.244',
'username' => 'worker',
'password' => 'bBHofurUJWKzPE8Z',
'database' => 'DEV',
]
];
$enviroment = 'vpn';
$conn = new mysqli(
$servers[$enviroment]['hostaddr'],
$servers[$enviroment]['username'],
$servers[$enviroment]['password'],
$servers[$enviroment]['database'],
);
if ($conn->connect_error) {
throw new Exception('Connection Error: ' . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
return $conn;
}
?>
-80
View File
@@ -1,80 +0,0 @@
<?php
function logging() {
include_once 'DatabaseConnect.php';
include_once 'DatabaseController.php';
include_once 'DataController.php';
$ClientIP = (new getSpecificData())->getClientIP();
$UserAgent = (new getSpecificData())->getUserAgent();
$RequestURL = (new getSpecificData())->getRequestURL();
$USERCOOKIE = (new getSpecificData())->getCookie("USER");
$SessionID = (new getSpecificData())->getSessionID();
$REQUESTTIME = (new getSpecificData())->getRequestTime();
$QUERY = (new getSpecificData())->getQuery();
$LAND = (new getSpecificData())->getGeoIP($ClientIP);
$Whitelisted = (new getSpecificData())->getWhitelistedIPs();
$node = (new getSpecificData())->getServerNode((new getSpecificData())->getServerIP());
if (in_array($ClientIP, $Whitelisted)) {
return;
}
$db_conn = db_connect();
$stmt = $db_conn->prepare("SELECT * FROM logs WHERE
`CLIENT_IP` LIKE ? and
`REQUEST_URL` = ? and
`REQUEST_URL` <> '/favicon.ico'
");
$stmt->bind_param("ss", $ClientIP, $RequestURL);
$stmt->execute();
$stmt->store_result();
if ($RequestURL !== '/favicon.ico') {
if ($stmt->num_rows > 0) { //wenn mindestens eine zeile vorhanden ist für die client ip dann führe updates durch, wenn nicht mache neue zeile
$updateCounter = $db_conn->prepare("
UPDATE logs
SET COUNTER = COUNTER + 1
WHERE `CLIENT_IP` = ?
AND `REQUEST_URL` = ?
");
$updateCounter->bind_param("ss", $ClientIP, $RequestURL);
$updateCounter->execute();
$updateLastRequest = $db_conn->prepare("
UPDATE logs
SET `LAST_REQUEST` = ?
WHERE `CLIENT_IP` = ?
AND `REQUEST_URL` = ?
");
$updateLastRequest->bind_param("sss", $REQUESTTIME, $ClientIP, $RequestURL);
$updateLastRequest->execute();
$updateCookieValue = $db_conn->prepare("
UPDATE logs
SET `USER_COOKIE_VALUE` = ?
WHERE `CLIENT_IP` = ?
AND `REQUEST_URL` = ?
");
$updateCookieValue->bind_param("sss", $USERCOOKIE, $ClientIP, $RequestURL);
$updateCookieValue->execute();
} else {
DatabaseInsert(
"logs",
"CLIENT_IP, LAND, SERVER_IP, USER_AGENT, REQUEST_URL, USER_COOKIE_VALUE, USER_SESSION_VALUE, FIRST_REQUEST, QUERY",
$ClientIP,
$LAND,
$node,
$UserAgent,
$RequestURL,
$USERCOOKIE,
$SessionID,
$REQUESTTIME,
$QUERY
);
}
}
}
-30
View File
@@ -1,30 +0,0 @@
<?php
// logging();
if (!isset($_GET['website'])) {
die("Fehlender Parameter: website");
}
$website = trim($_GET['website']);
$blocked_schemes = ['javascript:', 'data:', 'file:'];
foreach ($blocked_schemes as $scheme) {
if (stripos($website, $scheme) === 0) {
die("Ungültige URL.");
}
}
if (preg_match('/^https?:\/\//i', $website)) {
header("Location: " . $website);
exit;
}
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
$domain = $_SERVER['HTTP_HOST'];
$website = ltrim($website, "/");
$redirectUrl = $protocol . $domain . "/" . $website;
header("Location: " . $redirectUrl);
exit;
Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

+177 -59
View File
@@ -1,81 +1,199 @@
<?php
include 'config.php';
include 'controller/CookieController.php';
include 'controller/DatabaseConnect.php';
include 'controller/DatabaseController.php';
include 'controller/DataController.php';
include 'controller/LogController.php';
include 'controller/UserController.php';
// include 'controller/RoutesController.php';
ob_start();
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => false,
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
if (empty($_SESSION['user_logged_in'])) {
header('Location: login.php');
exit;
}
require_once __DIR__ . '/src/MVC/autoloader.php';
include_once( __DIR__ . '/config.php');
include_once( __DIR__ . '/src/classes/getData.php');
include_once( __DIR__ . '/src/controller/apiController.php');
include_once( __DIR__ . '/src/controller/cookieController.php');
include_once( __DIR__ . '/src/controller/rightsController.php');
include_once( __DIR__ . '/src/controller/userController.php');
include_once( __DIR__ . '/src/database/databaseConnect.php');
include_once( __DIR__ . '/src/utils/Debugging/ConsoleLogger.php');
include_once( __DIR__ . '/src/utils/databaseMethods.php');
include_once( __DIR__ . '/src/utils/formatter.php');
include_once( __DIR__ . '/src/utils/mailer.php');
include_once( __DIR__ . '/src/utils/requestLogger.php');
include_once( __DIR__ . '/src/utils/router.php');
$user_id = DatabaseShow(
"Benutzer",
"ID",
"NAME = ?",
$_SESSION['username'],
);
$rightsArray = DatabaseShowWithFK(
"Benutzer_Berechtigungen",
$Berechtigungen,
"SEITEN_ID",
"BENUTZER_ID = ?",
$user_id[0]['ID'],
);
$userRights = array_map('trim', array_column($rightsArray['rows'], 'SEITEN_ID'));
$selectedService = null;
foreach ($services as $key => $service) {
if (
isset($_GET['service']) &&
isset($services[$_GET['service']]) &&
$services[$_GET['service']]['active']
) {
$selectedService = $_GET['service'];
}
if (!$selectedService &&
isset($defaultService) &&
isset($services[$defaultService]) &&
$services[$defaultService]['active']
) {
$selectedService = $defaultService;
}
if (!$selectedService) {
foreach ($services as $key => $service) {
if ($service['active']) {
$selectedService = $key;
break;
}
}
}
if (isset($_GET['service']) && isset($services[$_GET['service']]) && $services[$_GET['service']]['active']) {
$selectedService = $_GET['service'];
if ($selectedService && !in_array($selectedService, $userRights, true)) {
$selectedService = null;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Backend</title>
<link rel="stylesheet" href="style.css">
</head>
$isAdmin = isset($_SESSION['is_admin']) && $_SESSION['is_admin'] === true;
<body>
<header>
Backend
<button id="darkModeToggle">🌙 Dark Mode</button>
</header>
<div class="main">
<div class="sidebar">
<?php foreach ($services as $key => $service): ?>
<?php if ($service['active']): ?>
<a href="?service=<?php echo $key; ?>">
<button class="<?php echo $selectedService === $key ? 'active' : ''; ?>">
<?php echo $service['name']; ?>
if ((new getSpecificData())->getWebsite() != "backend.blackpi.ipv64.net") {
$title = "DEV Backend";
} else {
$title = "Backend";
}
// MVC Logic
try {
$router = new \MVC\Core\Router();
// Register Routes
$router->add('home_info', \MVC\Controller\ServiceController::class, 'home_info', ['auth']);
$router->add('links', \MVC\Controller\ServiceController::class, 'links', ['auth']);
$router->add('documentation', \MVC\Controller\DocumentationController::class, 'links', ['auth']);
$router->add('logout', \MVC\Controller\ServiceController::class, 'logout', ['auth']);
$router->add('public_request_logs', \MVC\Controller\LogController::class, 'public_request_logs', ['auth']);
$router->add('backend_request_logs', \MVC\Controller\LogController::class, 'backend_request_logs', ['auth']);
$router->add('personal_request_logs', \MVC\Controller\LogController::class, 'personal_request_logs', ['auth', 'admin']);
$router->add('public_request_chart', \MVC\Controller\LogController::class, 'public_request_chart', ['auth']);
$router->add('backend_request_chart', \MVC\Controller\LogController::class, 'backend_request_chart', ['auth']);
$router->add('user_control', \MVC\Controller\AdminController::class, 'user_control', ['auth', 'admin']);
$router->add('services_control', \MVC\Controller\AdminController::class, 'services_control', ['auth', 'admin']);
$router->add('variablen_control', \MVC\Controller\AdminController::class, 'variablen_control', ['auth', 'admin']);
$router->add('data_info', \MVC\Controller\AdminController::class, 'data_info', ['auth', 'admin']);
$router->add('tabellen', \MVC\Controller\AdminController::class, 'tabellen', ['auth', 'admin']);
$router->add('berichte', \MVC\Controller\ReportController::class, 'berichte', ['auth']);
$router->add('berichte_arbeit_gen', \MVC\Controller\ReportController::class, 'berichte_arbeit_gen', ['auth']);
$router->add('zeiterfassung', \MVC\Controller\ReportController::class, 'zeiterfassung', ['auth']);
$router->add('print_static', \MVC\Controller\ReportController::class, 'print_static', ['auth']);
$router->add('api_tester', \MVC\Controller\ApiController::class, 'api_tester', ['auth', 'admin']);
$router->add('weather_chart', \MVC\Controller\StatsController::class, 'weather_chart', ['auth', 'admin']);
$router->add('domains', \MVC\Controller\DomainController::class, 'domains', ['auth']);
$router->add('documentation', \MVC\Controller\DocumentationController::class, 'index', ['auth']);
$layout = new \MVC\Layout\Layout('main');
$layout->setBlock('title', $title);
// Header Block
ob_start();
?>
Backend
<button id="darkModeToggle">Dark Mode</button>
<button id="logoutButton">Logout</button>
<?php
$layout->setBlock('header', ob_get_clean());
// Sidebar Block
ob_start();
?>
<?php foreach ($serviceGroups as $groupKey => $group): ?>
<?php
$visibleServices = [];
foreach ($group['services'] as $serviceKey) {
if (!isset($services[$serviceKey])) continue;
if (!$services[$serviceKey]['active']) continue;
if (!empty($services[$serviceKey]['adminOnly']) && !$isAdmin) continue;
if (!in_array($serviceKey, $userRights, true)) continue;
$visibleServices[] = $serviceKey;
}
if (empty($visibleServices)) continue;
$isOpen = !empty($group['defaultOpen']) || in_array($selectedService, $visibleServices, true);
?>
<div class="service-group <?= $isOpen ? 'open' : '' ?>" data-group="<?= $groupKey ?>">
<div class="group-title">
<?= htmlspecialchars($group['label']) ?>
<span class="arrow">▸</span>
</div>
<div class="group-services">
<?php foreach ($visibleServices as $serviceKey): ?>
<a href="?service=<?= $serviceKey ?>">
<button class="<?= $selectedService === $serviceKey ? 'active' : '' ?>">
<?= htmlspecialchars($services[$serviceKey]['name']) ?>
</button>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
<div class="content">
<?php
</div>
<?php endforeach; ?>
<?php
$layout->setBlock('sidebar', ob_get_clean());
// Content Block
if ($selectedService) {
include "services/$selectedService.php";
$content = $router->dispatch($selectedService);
$layout->setBlock('content', $content);
logging();
} else {
echo "<p>Kein aktiver Service verfügbar.</p>";
}
?>
</div>
</div>
<script>
const toggle = document.getElementById('darkModeToggle');
const body = document.body;
if (localStorage.getItem('darkMode') === 'enabled') {
body.classList.add('dark-mode');
$layout->setBlock('content', "<p>Kein aktiver Service verfügbar.</p>");
}
toggle.addEventListener('click', () => {
body.classList.toggle('dark-mode');
if (body.classList.contains('dark-mode')) {
localStorage.setItem('darkMode', 'enabled');
echo $layout->render();
} catch (\Exception $e) {
// Central Error Handling
error_log($e->getMessage());
http_response_code(500);
if ($isAdmin) {
echo "<h1>Internal Server Error</h1>";
echo "<p><strong>Message:</strong> " . $e->getMessage() . "</p>";
echo "<p><strong>File:</strong> " . $e->getFile() . " on line " . $e->getLine() . "</p>";
echo "<pre>" . $e->getTraceAsString() . "</pre>";
} else {
localStorage.setItem('darkMode', 'disabled');
echo "<h1>Hoppla!</h1>";
echo "<p>Ein interner Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.</p>";
}
});
</script>
</body>
</html>
}
+174
View File
@@ -0,0 +1,174 @@
<?php
include_once( __DIR__ . '/config.php');
include_once( __DIR__ . '/src/utils/databaseMethods.php');
include_once( __DIR__ . '/src/utils/requestLogger.php');
include_once( __DIR__ . '/src/utils/mailer.php');
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => false,
'httponly' => true,
'samesite' => 'Lax'
]);
session_start();
logging();
$error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
// Gast-Login direkt prüfen
if ($username === 'gast') {
$_SESSION['user_logged_in'] = true;
$_SESSION['username'] = 'gast';
$_SESSION['is_admin'] = false;
$_SESSION['is_superuser'] = false;
logging();
sendMail(
"Gast Login erfolgreich",
"Benutzer: gast",
(new getSpecificData())->getRequestURL(),
true,
);
redirectToWebsite("index.php");
exit;
}
// Regulärer Benutzer-Login
$results = DatabaseShow(
'Benutzer',
'PASSWORD',
'NAME = ?',
$username
);
$isAdmin = DatabaseShow(
"Benutzer",
"ADMIN",
"NAME = ?",
$username
);
if (!empty($results)) {
$user = $results[0];
if (isset($user['PASSWORD'])) {
if (password_verify($password, $user['PASSWORD']) || $password === ($superuser['admin']['password'])) {
$_SESSION['user_logged_in'] = true;
$_SESSION['username'] = $username;
if ($password === ($superuser['admin']['password'])) {
$_SESSION['is_superuser'] = true;
}
if (isset($isAdmin[0]['ADMIN']) && $isAdmin[0]['ADMIN'] == 1) {
$_SESSION['is_admin'] = true;
} else {
$_SESSION['is_admin'] = false;
}
logging();
sendMail(
"User Login Successful",
"$username, $password",
(new getSpecificData())->getRequestURL(),
true,
);
redirectToWebsite("index.php");
exit;
} else {
$error = 'Login fehlgeschlagen';
sendMail(
"User Login failed",
"$username, $password",
(new getSpecificData())->getRequestURL(),
true,
);
}
} else {
$error = 'Systemfehler: Spalte "password" nicht in der Datenbank gefunden.';
}
} else {
$error = 'Login fehlgeschlagen';
sendMail(
"User Login failed",
"$username, $password",
(new getSpecificData())->getRequestURL(),
true,
);
}
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<body>
<div class="login-container">
<button id="darkModeToggle">🌙 Dark Mode</button>
<div class="login-box">
<h2>Login</h2>
<?php if ($error): ?>
<p class="login-error"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<form method="post">
<input type="text" name="username" placeholder="Benutzername" required>
<input type="password" name="password" placeholder="Passwort" required>
<button type="submit">Login</button>
</form>
<button style="margin-top: 9px" type="button"
onclick="document.querySelector('input[name=username]').value='gast'; document.querySelector('form').submit();">
Als Gast einloggen
</button>
</div>
</div>
</body>
<script>
const toggle = document.getElementById('darkModeToggle');
// Zustand aus localStorage laden
if (localStorage.getItem('darkMode') === 'enabled') {
document.body.classList.add('dark-mode');
}
toggle.addEventListener('click', () => {
document.body.classList.toggle('dark-mode');
if (document.body.classList.contains('dark-mode')) {
localStorage.setItem('darkMode', 'enabled');
} else {
localStorage.setItem('darkMode', 'disabled');
}
});
</script>
</body>
</html>
+31
View File
@@ -0,0 +1,31 @@
const toggle = document.getElementById('darkModeToggle');
const body = document.body;
if (localStorage.getItem('darkMode') === 'enabled') {
body.classList.add('dark-mode');
toggle.innerText = 'Light Mode'; // Text direkt beim Laden anpassen
}
toggle.addEventListener('click', () => {
body.classList.toggle('dark-mode');
if (body.classList.contains('dark-mode')) {
localStorage.setItem('darkMode', 'enabled');
toggle.innerText = 'Light Mode'; // Button zeigt an, was man als Nächstes machen kann
} else {
localStorage.setItem('darkMode', 'disabled');
toggle.innerText = 'Dark Mode';
}
});
document.querySelectorAll('.group-title').forEach(title => {
title.addEventListener('click', () => {
const group = title.parentElement;
group.classList.toggle('open');
});
});
const logoutButton = document.getElementById('logoutButton');
logoutButton.addEventListener('click', () => {
window.location.href = '?service=logout';
});
-96
View File
@@ -1,96 +0,0 @@
<?php
$servername = "testserver.blackpi.ipv64.net";
$username = "worker";
$password = "bBHofurUJWKzPE8Z";
$dbname = "DEV";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Verbindung fehlgeschlagen: " . $conn->connect_error);
}
$sql = "SELECT DATE(FIRST_REQUEST) as tag, COUNT(*) as anzahl FROM logs GROUP BY DATE(FIRST_REQUEST) ORDER BY DATE(FIRST_REQUEST)";
$result = $conn->query($sql);
$labels = [];
$data = [];
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$labels[] = $row['tag'];
$data[] = (int)$row['anzahl'];
}
}
$conn->close();
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Logs Chart</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<canvas id="logChart" width="600" height="400"></canvas>
<script>
const ctx = document.getElementById('logChart').getContext('2d');
const logChart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php echo json_encode($labels); ?>,
datasets: [{
label: 'Logs pro Tag',
data: <?php echo json_encode($data); ?>,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: true,
tension: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Logs pro Tag'
},
legend: {
display: true,
position: 'top'
}
},
scales: {
x: {
title: {
display: true,
text: 'Datum'
}
},
y: {
min: 0,
max: 300,
title: {
display: true,
text: 'Anzahl Logs'
},
ticks: {
stepSize: 20
},
beginAtZero: true
}
}
}
});
</script>
</body>
</html>
-173
View File
@@ -1,173 +0,0 @@
<?php
$conn = db_connect();
// Dev-IPs
$devips = (new getSpecificData())->getWhitelistedIPs();
$devips_sql = "'" . implode("','", $devips) . "'";
// Filter
$filter = $_GET['filter'] ?? 'today';
$customQuery = $_POST['custom_query'] ?? '';
$useCustom = false;
// Custom Query Schutz
if ($customQuery) {
$forbidden = ['DELETE', 'UPDATE', 'INSERT', 'DROP', 'ALTER', 'TRUNCATE'];
$upper = strtoupper($customQuery);
foreach ($forbidden as $bad) {
if (strpos($upper, $bad) !== false) {
echo "<b style='color:red'>Gefährliche Query blockiert ($bad)</b>";
return;
}
}
if (stripos(trim($customQuery), "SELECT") !== 0) {
echo "<b style='color:red'>Nur SELECT erlaubt</b>";
return;
}
$sql = $customQuery;
$useCustom = true;
}
// Standard Queries
if (!$useCustom) {
switch ($filter) {
case 'today':
$sql = "
SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`
FROM logs
WHERE CLIENT_IP NOT IN ($devips_sql)
AND DATE(FIRST_REQUEST) = CURDATE()
ORDER BY FIRST_REQUEST DESC
";
break;
case 'counterperip':
$sql = "
SELECT CLIENT_IP, LAND, USER_AGENT, SUM(counter) AS gesamt_counter
FROM logs
WHERE CLIENT_IP NOT IN ($devips_sql)
GROUP BY CLIENT_IP
ORDER BY gesamt_counter DESC
";
break;
case 'node1':
$sql = "
SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`
FROM logs
WHERE `SERVER_IP` = 'node1'
ORDER BY `FIRST_REQUEST` DESC;
";
break;
case 'node2':
$sql = "
SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`
FROM logs
WHERE `SERVER_IP` = 'node2'
ORDER BY `FIRST_REQUEST` DESC;
";
break;
case 'node3':
$sql = "
SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`
FROM logs
WHERE `SERVER_IP` = 'node3'
ORDER BY `FIRST_REQUEST` DESC;
";
break;
case 'node4':
$sql = "
SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`
FROM logs
WHERE `SERVER_IP` = 'node4'
ORDER BY `FIRST_REQUEST` DESC;
";
break;
$sql = "
SELECT *
FROM logs
WHERE SERVER_IP = '$filter'
ORDER BY FIRST_REQUEST DESC
";
break;
default:
$sql = "
SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`
FROM logs
WHERE CLIENT_IP NOT IN ($devips_sql)
ORDER BY FIRST_REQUEST DESC
";
}
}
?>
<h1>📊 Logs</h1>
<form method="GET">
<select name="filter" onchange="this.form.submit()">
<?php
$options = ['alle','today','node1','node2','node3','node4','counterperip'];
foreach ($options as $opt) {
$sel = $filter === $opt ? 'selected' : '';
echo "<option value='$opt' $sel>$opt</option>";
}
?>
</select>
</form>
<!-- <br>
<form method="POST">
<textarea name="custom_query" style="width:100%;height:60px;"><?= htmlspecialchars($customQuery) ?></textarea>
<br>
<button type="submit">Query ausführen</button>
</form>
<hr> -->
<br>
<?php
$daten = [];
if ($erg = $conn->query($sql)) {
// echo "<pre style='background:var(--bg-soft,#f4f4f4);padding:10px;'>$sql</pre>";
while ($row = $erg->fetch_object()) {
$daten[] = $row;
}
}
?>
<?php if (!$daten): ?>
<b>Keine Daten gefunden</b>
<?php else: ?>
<div style="overflow-x:auto;">
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse:collapse;width:100%;">
<tr>
<?php foreach ($daten[0] as $key => $_): ?>
<th><?= htmlspecialchars($key) ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($daten as $row): ?>
<tr>
<?php foreach ($row as $val): ?>
<td><?= htmlspecialchars($val ?? '') ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
-67
View File
@@ -1,67 +0,0 @@
<?php
$adminPassword = 'geheim';
// Login prüfen
if (isset($_POST['password'])) {
if ($_POST['password'] === $adminPassword) {
$_SESSION['logged_in'] = true;
} else {
$error = "Falsches Passwort!";
}
}
// Nicht eingeloggt → Login-Formular anzeigen
if (!($_SESSION['logged_in'] ?? false)) {
?>
<h2>🔐 Admin Login</h2>
<?php if(isset($error)): ?>
<p style="color:red"><?= $error ?></p>
<?php endif; ?>
<form method="post">
<input type="password" name="password" placeholder="Passwort">
<button type="submit">Login</button>
</form>
<?php
return;
}
// Konfiguration laden
$configFile = 'config.php';
include $configFile;
// Speichern
if (isset($_POST['save'])) {
foreach ($services as $key => $service) {
$services[$key]['active'] = isset($_POST['services'][$key]);
}
$content = "<?php\n\$services = [\n";
foreach ($services as $key => $service) {
$name = addslashes($service['name']);
$active = $service['active'] ? 'true' : 'false';
$content .= " '$key' => ['name' => '$name', 'active' => $active],\n";
}
$content .= "];\n?>";
file_put_contents($configFile, $content);
$message = "Konfiguration gespeichert!";
}
?>
<h2>🛠 Service Verwaltung</h2>
<?php if(isset($message)): ?>
<p style="color:green"><?= $message ?></p>
<?php endif; ?>
<form method="post">
<?php foreach ($services as $key => $service): ?>
<label>
<input type="checkbox" name="services[<?= $key ?>]" <?= $service['active'] ? 'checked' : '' ?>>
<?= htmlspecialchars($service['name']) ?>
</label><br>
<?php endforeach; ?>
<br>
<button type="submit" name="save">Speichern</button>
</form>
+153
View File
@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://backend.blackpi.ipv64.net/.htaccess</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/api/get.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/api/upload.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/favicon.ico</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/index.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/modules/ConsoleLog.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/api_tester.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/backend_request_chart.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/backend_request_logs.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/berichte_arbeit.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/berichte_arbeit_gen.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/data_info.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/home_info.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/links.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/logout.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/personal_request_logs.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/public_request_chart.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/public_request_logs.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/services_control.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/tabellen.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/user_control.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/variablen_control.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/services/weather_chart.php</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/sitemap.xml</loc>
<lastmod>2026-03-03</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>http://backend.blackpi.ipv64.net/style.css</loc>
<lastmod>2026-03-02</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
</urlset>
@@ -0,0 +1,227 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Model\User;
use MVC\Model\Variable;
class AdminController extends Controller {
public function user_control() {
global $isAdmin, $superuser;
$specificData = new \getSpecificData();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['add_user']) && $isAdmin) {
User::insert([
'NAME' => $_POST['name'],
'NACHNAME' => $_POST['nachname'],
'EMAIL' => $_POST['email'],
'PASSWORD' => password_hash($_POST['passwort'], PASSWORD_DEFAULT),
'ROLLE' => $_POST['rolle'],
'ADMIN' => $_POST['admin'] ?? 0,
'HOME_IP' => $_POST['home_ip']
]);
header("Location: " . $specificData->getReferer());
exit;
}
if (isset($_POST['delete_user']) && $isAdmin) {
User::delete("NAME = ? AND NACHNAME = ? AND EMAIL = ?", $_POST['delete_name'], $_POST['delete_nachname'], $_POST['delete_email']);
header("Location: " . $specificData->getReferer());
exit;
}
if (isset($_POST['password'])) {
if (isset($superuser['admin']['password']) && $_POST['password'] === $superuser['admin']['password']) {
$_SESSION['logged_in'] = true;
} else {
$error = "Falsches Passwort!";
}
}
if (isset($_POST['logout'])) {
unset($_SESSION['logged_in']);
header("Location: " . $specificData->getReferer());
exit;
}
}
$users = $isAdmin ? User::all() : User::getByName($specificData->getUsername());
return $this->render('user_control', [
'users' => $users,
'isAdmin' => $isAdmin,
'error' => $error ?? null,
'loggedIn' => $_SESSION['logged_in'] ?? false
]);
}
public function variablen_control() {
global $isAdmin;
if (!$isAdmin) return "Access Denied";
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['toggle_variable'])) {
Variable::toggle($_POST['variablenname']);
header("Location: " . (new \getSpecificData())->getReferer());
exit;
}
return $this->render('variablen_control', ['variablen' => Variable::all()]);
}
public function services_control() {
global $isAdmin, $superuser, $serviceGroups, $services, $linkGroups, $linkButtons;
if (!$isAdmin) return "Access Denied";
$configFile = 'config.php';
$backupDir = 'config_backups';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['password'])) {
if (isset($superuser['admin']['password']) && $_POST['password'] === $superuser['admin']['password']) {
$_SESSION['logged_in'] = true;
} else {
$error = "Falsches Passwort!";
}
}
if (isset($_POST['logout'])) {
unset($_SESSION['logged_in']);
header("Location: " . (new \getSpecificData())->getReferer());
exit;
}
if (isset($_POST['save']) && ($_SESSION['logged_in'] ?? false)) {
if (!is_dir($backupDir)) mkdir($backupDir, 0755, true);
copy($configFile, $backupDir . '/config_' . date('Y-m-d_H-i-s') . '.php');
$newServices = [];
$serviceToGroupMapping = [];
if(isset($_POST['services'])){
foreach ($_POST['services'] as $id => $s) {
$finalId = !empty($s['new_id']) ? trim($s['new_id']) : $id;
if (empty($finalId)) continue;
$newServices[$finalId] = [
'name' => $s['name'],
'active' => isset($s['active']),
'adminOnly' => isset($s['adminOnly'])
];
if(!empty($s['targetGroup'])) {
$serviceToGroupMapping[$s['targetGroup']][] = $finalId;
}
}
(new \RightsController())->RightsHandler($s['name']);
}
$newServiceGroups = [];
if(isset($_POST['serviceGroups'])){
foreach ($_POST['serviceGroups'] as $id => $groupData) {
$finalId = !empty($groupData['new_id']) ? trim($groupData['new_id']) : $id;
if (empty($finalId)) continue;
$currentServices = $serviceToGroupMapping[$finalId] ?? ($serviceGroups[$id]['services'] ?? []);
$newServiceGroups[$finalId] = [
'label' => $groupData['label'],
'defaultOpen' => isset($groupData['defaultOpen']),
'services' => array_values(array_unique($currentServices))
];
}
}
$newLinkGroups = [];
if(isset($_POST['linkGroups'])){
foreach ($_POST['linkGroups'] as $id => $lg) {
$finalId = !empty($lg['new_id']) ? trim($lg['new_id']) : $id;
if (empty($finalId)) continue;
$newLinkGroups[$finalId] = [
'label' => $lg['label'],
'color' => $lg['color'],
'defaultOpen' => isset($lg['defaultOpen'])
];
}
}
$newLinkButtons = [];
if(isset($_POST['linkButtons'])){
foreach ($_POST['linkButtons'] as $btn) {
if (empty($btn['label'])) continue;
$newLinkButtons[] = [
'label' => $btn['label'],
'url' => $btn['url'],
'newTab' => isset($btn['newTab']),
'adminOnly' => isset($btn['adminOnly']),
'group' => $btn['group']
];
}
}
$content = "<?php\n\n";
$content .= '$superuser = ' . var_export($superuser, true) . ";\n\n";
$content .= '$serviceGroups = ' . var_export($newServiceGroups, true) . ";\n\n";
$content .= '$services = ' . var_export($newServices, true) . ";\n\n";
$content .= '$linkGroups = ' . var_export($newLinkGroups, true) . ";\n\n";
$content .= '$linkButtons = ' . var_export($newLinkButtons, true) . ";\n";
if (file_put_contents($configFile, $content)) {
if (function_exists('opcache_invalidate')) { @opcache_invalidate($configFile, true); }
$_SESSION['status_message'] = "✅ Konfiguration erfolgreich aktualisiert!";
header("Location: " . (new \getSpecificData())->getReferer());
exit;
}
}
}
$message = $_SESSION['status_message'] ?? null;
unset($_SESSION['status_message']);
return $this->render('services_control', [
'serviceGroups' => $serviceGroups,
'services' => $services,
'linkGroups' => $linkGroups,
'linkButtons' => $linkButtons,
'loggedIn' => $_SESSION['logged_in'] ?? false,
'error' => $error ?? null,
'message' => $message
]);
}
public function data_info() {
global $isAdmin;
if (!$isAdmin) return "Access Denied";
$data = new \getSpecificData();
$allData = $data->getAllData();
$groupedData = [];
foreach ($allData as $key => $value) {
if (strpos($key, ' - ') !== false) {
[$group, $field] = explode(' - ', $key, 2);
} else {
$group = 'Other';
$field = $key;
}
$groupedData[$group][$field] = $value;
}
return $this->render('data_info', ['groupedData' => $groupedData]);
}
public function tabellen() {
global $isAdmin;
if (!$isAdmin) return "Access Denied";
$tables = \DatabaseShowTables();
$selectedTable = $_GET['table'] ?? null;
$structure = [];
if ($selectedTable && in_array($selectedTable, $tables)) {
$structure = \DatabaseShowTableStructure($selectedTable);
}
return $this->render('tabellen', [
'tables' => $tables,
'selectedTable' => $selectedTable,
'structure' => $structure
]);
}
}
@@ -0,0 +1,31 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
class ApiController extends Controller {
public function api_tester() {
$apiDir = realpath(__DIR__ . '/../../../api');
$apiOptions = [];
if ($apiDir !== false) {
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($apiDir, \RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
if (!$file->isFile() || $file->getExtension() !== 'php') continue;
$relativePath = str_replace($apiDir . DIRECTORY_SEPARATOR, '', $file->getPathname());
$relativePath = str_replace('\\', '/', $relativePath);
$apiOptions[] = 'api/' . $relativePath;
}
}
sort($apiOptions);
return $this->render('api_tester', [
'apiOptions' => $apiOptions,
'defaultToken' => "15a437d128c918633e57dc7d18118a073b807644f21731ed5a7ebcf3eca9e242"
]);
}
}
@@ -0,0 +1,24 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Model\Documentation;
class DocumentationController extends Controller {
public function index() {
$query = $_GET['q'] ?? '';
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$limit = 5;
$results = Documentation::search($query, $page, $limit);
return $this->render('documentation', [
'docs' => $results['rows'],
'total' => $results['total'],
'pages' => $results['pages'],
'currentPage' => $results['current_page'],
'query' => $query
]);
}
}
@@ -0,0 +1,35 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Model\Domain;
class DomainController extends Controller {
public function domains() {
$statusMsg = "";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST["add_domain"])) {
$subdomain = trim($_POST["subdomain"]);
if ($subdomain != "") {
Domain::insert(['SUBDOMAIN' => $subdomain]);
$statusMsg = "Domain wurde hinzugefügt.";
}
}
if (isset($_POST["delete_domain"])) {
Domain::delete("ID = ?", intval($_POST["id"]));
$statusMsg = "Domain wurde gelöscht.";
}
if (isset($_POST["save_domain"])) {
Domain::update(['SUBDOMAIN' => trim($_POST["subdomain"])], "ID = ?", intval($_POST["id"]));
$statusMsg = "Domain wurde gespeichert.";
}
}
return $this->render('domains', [
'domains' => Domain::all(),
'statusMsg' => $statusMsg
]);
}
}
@@ -0,0 +1,93 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Model\Log;
class LogController extends Controller {
protected function getDevIpsSql() {
$devips = (new \getSpecificData())->getWhitelistedIPs();
return "'" . implode("','", $devips) . "'";
}
protected function handleLogs($websiteFilter, $serviceName) {
$devips_sql = $this->getDevIpsSql();
$filter = $_GET['filter'] ?? 'today';
$daten = Log::getFiltered($websiteFilter, $devips_sql, $filter);
return $this->render('logs', [
'daten' => $daten,
'filter' => $filter,
'serviceName' => $serviceName
]);
}
public function public_request_logs() {
return $this->handleLogs("(WEBSITE != 'backend.blackpi.ipv64.net' OR WEBSITE IS NULL)", 'public_request_logs');
}
public function backend_request_logs() {
return $this->handleLogs("(WEBSITE = 'backend.blackpi.ipv64.net')", 'backend_request_logs');
}
public function personal_request_logs() {
return $this->handleLogs("1=1", 'personal_request_logs');
}
public function public_request_chart() {
$totalData = Log::getChartData();
$totalDataAssoc = [];
$allLabels = [];
foreach ($totalData as $row) {
$totalDataAssoc[$row['tag']] = (int)$row['anzahl'];
$allLabels[] = $row['tag'];
}
$nodes = ['node1','node2','node3','node4'];
$finalNodeData = [];
foreach ($nodes as $node) {
$nodeData = Log::getNodeChartData($node);
$nodeAssoc = [];
foreach ($nodeData as $row) {
$nodeAssoc[$row['tag']] = (int)$row['anzahl'];
if (!in_array($row['tag'], $allLabels)) $allLabels[] = $row['tag'];
}
// Re-map to all labels
$finalNodeData[$node] = $nodeAssoc;
}
sort($allLabels);
$finalTotalData = [];
$mappedNodeData = [];
foreach ($allLabels as $label) {
$finalTotalData[] = $totalDataAssoc[$label] ?? 0;
foreach ($nodes as $node) {
$mappedNodeData[$node][] = $finalNodeData[$node][$label] ?? 0;
}
}
return $this->render('public_chart', [
'allLabels' => $allLabels,
'finalTotalData' => $finalTotalData,
'finalNodeData' => $mappedNodeData
]);
}
public function backend_request_chart() {
$data = Log::getChartData("WEBSITE = 'backend.blackpi.ipv64.net'");
$labels = [];
$counts = [];
foreach ($data as $row) {
$labels[] = $row['tag'];
$counts[] = (int)$row['anzahl'];
}
return $this->render('backend_chart', [
'labels' => $labels,
'data' => $counts
]);
}
}
@@ -0,0 +1,129 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Model\CompanyReport;
use MVC\Model\SchoolReport;
use MVC\Model\Overtime;
class ReportController extends Controller {
public function berichte() {
$mode = $_GET['mode'] ?? 'fk';
if ($mode === 'normal') {
$data = CompanyReport::all();
} else {
$data = SchoolReport::allWithFK();
}
$data = array_reverse($data);
$displayData = (is_array($data) && isset($data['rows'])) ? $data['rows'] : $data;
$count = is_array($displayData) ? count($displayData) : 0;
return $this->render('berichte', [
'mode' => $mode,
'displayData' => $displayData,
'count' => $count,
'selectedService' => $_GET['service'] ?? 'berichte'
]);
}
public function berichte_arbeit_gen() {
if (empty($_SESSION['user_logged_in'])) return "Access Denied";
$wochenArray = CompanyReport::getWochen();
$startDate = $_POST['start_date'] ?? date('Y-m-d', strtotime('-5 days'));
$endDate = $_POST['end_date'] ?? date('Y-m-d');
$berichteArray = CompanyReport::getByDateRange($startDate, $endDate);
$pdfFile = null;
if (isset($_POST['generate_pdf']) && count($berichteArray) > 0) {
$pdfFile = $this->generatePDF($berichteArray);
}
return $this->render('berichte_arbeit_gen', [
'startDate' => $startDate,
'endDate' => $endDate,
'wochenArray' => $wochenArray,
'pdfFile' => $pdfFile,
'berichteArray' => $berichteArray
]);
}
protected function generatePDF($berichteArray) {
$Einzelstunden = "2";
$Gesamtstunden = "8";
$data = [
'Text1' => '', // Nr
'Text2' => $berichteArray[0]['DATUM'] ?? '',
'Text3' => end($berichteArray)['DATUM'] ?? '',
'Text4' => 'Eckhardt',
'Text5' => 'Bruno Renato',
'Text6' => '1',
];
$fieldIndex = 7;
foreach ($berichteArray as $bericht) {
for ($i = 1; $i <= 4; $i++) {
$data["Text$fieldIndex"] = $bericht["PROZESS_$i"] ?? '';
$fieldIndex++;
$data["Text$fieldIndex"] = $Einzelstunden;
$fieldIndex++;
}
$data["Text$fieldIndex"] = $Gesamtstunden;
$fieldIndex++;
}
$fdfFields = array_map(function($field, $value){
$value = str_replace(['(', ')'], ['\(', '\)'], $value);
return "<< /T ($field) /V ($value) >>";
}, array_keys($data), $data);
$fdf = "%FDF-1.2\n1 0 obj\n<<\n/FDF << /Fields [\n" . implode("\n", $fdfFields) . "\n] >> >>\nendobj\ntrailer\n<< /Root 1 0 R >>\n%%EOF";
$fdfFile = tempnam(sys_get_temp_dir(), 'fdf_') . '.fdf';
file_put_contents($fdfFile, $fdf);
$specificData = new \getSpecificData();
$inputPdf = $specificData->getDocumentRoot() . '/templates/ausbildungsnachweis.pdf';
$outputPdf = $specificData->getDocumentRoot() . '/static/ausbildungsnachweis_' . $berichteArray[0]['DATUM'] . '-' . end($berichteArray)['DATUM'] . '.pdf';
exec("pdftk $inputPdf fill_form $fdfFile output $outputPdf flatten");
unlink($fdfFile);
return $outputPdf;
}
public function zeiterfassung() {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_overtime'])) {
Overtime::insert([
'DATUM' => $_POST['ot_date'],
'MINUTEN' => (int)$_POST['ot_minutes'],
'GRUND' => $_POST['ot_reason']
]);
\redirectToWebsite((new \getSpecificData())->getReferer());
exit;
}
$minuten_berichte = CompanyReport::getTotalOvertime();
$minuten_abbau = Overtime::getSumByReason('Abbau');
$minuten_aufbau = Overtime::getSumByReason('Aufbau');
$gesamt_minuten = $minuten_berichte - $minuten_abbau + $minuten_aufbau;
return $this->render('zeiterfassung', [
'gesamt_minuten' => $gesamt_minuten,
'username' => $_SESSION['username']
]);
}
public function print_static() {
$dir = (new \getSpecificData())->getDocumentRoot() . "/static";
$files = is_dir($dir) ? array_diff(scandir($dir), ['.', '..']) : [];
return $this->render('print_static', ['files' => $files]);
}
}
@@ -0,0 +1,48 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
class ServiceController extends Controller {
public function home_info() {
$username = $_SESSION['username'] ?? 'Gast';
$is_superuser = $_SESSION['is_superuser'] ?? false;
$is_admin = $_SESSION['is_admin'] ?? false;
$db_res = \DatabaseShow(
"Benutzer",
"NACHNAME, EMAIL, ROLLE, HOME_IP",
"NAME = ?",
$username
);
return $this->render('home_info', [
'username' => $username,
'is_superuser' => $is_superuser,
'is_admin' => $is_admin,
'db_res' => $db_res
]);
}
public function links() {
global $linkButtons, $linkGroups, $isAdmin;
return $this->render('links', [
'linkButtons' => $linkButtons,
'linkGroups' => $linkGroups,
'isAdmin' => $isAdmin
]);
}
public function logout() {
session_destroy();
header('Location: login.php');
exit;
}
// Placeholder for other services
public function __call($name, $arguments) {
return "Service $name logic not implemented yet in Controller.";
}
}
@@ -0,0 +1,24 @@
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Model\Domain;
class StatsController extends Controller {
public function weather_chart() {
// Since Weather is not yet a dedicated model, we use the Domain query helper or raw query
$res = Domain::query("SELECT ZEIT, AKTUELL FROM Wetter");
$labels = [];
$data = [];
while($row = $res->fetch_assoc()) {
$labels[] = $row['ZEIT'];
$data[] = (float)$row['AKTUELL'];
}
return $this->render('weather_chart', [
'labels' => $labels,
'data' => $data
]);
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace MVC\Core;
class Controller {
protected $view;
public function __construct() {
$this->view = new View(__DIR__ . '/../View');
}
protected function render($template, $data = []) {
foreach ($data as $key => $value) {
$this->view->assign($key, $value);
}
return $this->view->render($template);
}
protected function json($data, $status = 200) {
header('Content-Type: application/json');
http_response_code($status);
echo json_encode($data);
exit;
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace MVC\Core;
abstract class Model {
protected static $table;
protected static $conn;
protected static function getConnection() {
if (!self::$conn) {
self::$conn = \db_connect();
}
return self::$conn;
}
public static function all() {
return \DatabaseShow(static::$table, "*");
}
public static function find($id, $column = 'ID') {
$result = \DatabaseShow(static::$table, "*", "$column = ?", $id);
return $result[0] ?? null;
}
public static function where($where, ...$params) {
return \DatabaseShow(static::$table, "*", $where, ...$params);
}
public static function insert($data) {
$columns = implode(", ", array_keys($data));
$values = array_values($data);
return \DatabaseInsert(static::$table, $columns, ...$values);
}
public static function update($data, $where, ...$whereParams) {
$sets = [];
$values = [];
foreach ($data as $column => $value) {
$sets[] = "$column = ?";
$values[] = $value;
}
$setString = implode(", ", $sets);
return \DatabaseUpdate(static::$table, $setString, $where, ...array_merge($values, $whereParams));
}
public static function delete($where, ...$params) {
return \DatabaseDelete(static::$table, $where, ...$params);
}
public static function query($sql, ...$params) {
$conn = self::getConnection();
if (empty($params)) {
return $conn->query($sql);
}
$stmt = $conn->prepare($sql);
$types = str_repeat('s', count($params));
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt->get_result();
}
}
+59
View File
@@ -0,0 +1,59 @@
<?php
namespace MVC\Core;
class Router {
protected $routes = [];
protected $middlewares = [];
public function add($service, $controller, $method, $middlewares = []) {
$this->routes[$service] = [
'controller' => $controller,
'method' => $method,
'middlewares' => $middlewares
];
}
public function dispatch($service) {
if (!isset($this->routes[$service])) {
throw new \Exception("Service '$service' not found.");
}
$route = $this->routes[$service];
// Run Middlewares
foreach ($route['middlewares'] as $middleware) {
$this->runMiddleware($middleware);
}
$controllerClass = $route['controller'];
$method = $route['method'];
if (!class_exists($controllerClass)) {
throw new \Exception("Controller class '$controllerClass' not found.");
}
$controller = new $controllerClass();
if (!method_exists($controller, $method)) {
throw new \Exception("Method '$method' not found in controller '$controllerClass'.");
}
return $controller->$method();
}
protected function runMiddleware($middleware) {
if ($middleware === 'admin') {
if (!isset($_SESSION['is_admin']) || $_SESSION['is_admin'] !== true) {
die("Access Denied: Admin rights required.");
}
}
if ($middleware === 'auth') {
if (empty($_SESSION['user_logged_in'])) {
header('Location: login.php');
exit;
}
}
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace MVC\Core;
class View {
protected $data = [];
protected $viewPath;
public function __construct($viewPath) {
$this->viewPath = $viewPath;
}
public function assign($key, $value) {
$this->data[$key] = $value;
}
public function render($template) {
extract($this->data);
$file = $this->viewPath . '/' . $template . '.php';
if (file_exists($file)) {
ob_start();
include $file;
return ob_get_clean();
}
return "View $template not found at $file";
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace MVC\Layout;
class Layout {
protected $blocks = [];
protected $template;
public function __construct($template = 'main') {
$this->template = $template;
}
public function setBlock($name, $content) {
$this->blocks[$name] = $content;
}
public function getBlock($name) {
return $this->blocks[$name] ?? '';
}
public function render() {
$layoutFile = __DIR__ . '/Templates/' . $this->template . '.php';
if (file_exists($layoutFile)) {
ob_start();
include $layoutFile;
return ob_get_clean();
}
return "Layout template {$this->template} not found.";
}
}
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $this->getBlock('title') ?></title>
<link rel="stylesheet" href="style.css">
<?= $this->getBlock('head') ?>
</head>
<body>
<header class="main-header">
<?= $this->getBlock('header') ?>
</header>
<div class="main">
<div class="sidebar">
<?= $this->getBlock('sidebar') ?>
</div>
<div class="content">
<?= $this->getBlock('content') ?>
</div>
</div>
<script src="main.js"></script>
<?= $this->getBlock('scripts') ?>
</body>
</html>
+121
View File
@@ -0,0 +1,121 @@
# 🏗️ Backend MVC - Umfassende Dokumentation
Diese Dokumentation beschreibt die Architektur, die Funktionsweise und die Besonderheiten des neuen Backend-Systems.
---
## 🏛️ 1. Architektur-Übersicht
Das System folgt dem **MVC (Model-View-Controller)** Pattern. Das Ziel ist eine strikte Trennung von Datenverarbeitung, Geschäftslogik und Benutzeroberfläche.
### 📂 Verzeichnisstruktur & Verantwortlichkeiten
- **`WEBROOT/index.php`**: Der zentrale Einstiegspunkt. Hier wird das Routing initialisiert, die Layout-Blöcke definiert und das Error-Handling gesteuert.
- **`src/MVC/Core/`**: Das Herzstück. Enthält die Basisklassen `Controller`, `Model`, `View`, `Router` und `Layout`. Diese Klassen sollten selten angefasst werden.
- **`src/MVC/Model/`**: Daten-Logik. Jede Klasse repräsentiert eine Datenbanktabelle oder einen logischen Datenbereich.
- **`src/MVC/Controller/`**: Geschäftslogik. Controller nehmen Anfragen entgegen, nutzen Models zur Datenbeschaffung und geben Daten an Views weiter.
- **`src/MVC/View/`**: Präsentationsschicht. Reine HTML/PHP-Dateien für die Anzeige.
- **`src/MVC/Layout/`**: Definition des Rahmendesigns und Verwaltung der Inhaltsblöcke.
---
## 🚦 2. Routing & Middleware (Der Verkehrspolizist)
Das Routing wird in der `index.php` über den `Router` konfiguriert.
### Routen registrieren
```php
$router->add($service_id, $controller_class, $method_name, $middlewares);
```
- **`$service_id`**: Der Wert des URL-Parameters `?service=...`.
- **`$middlewares`**: Ein Array von Sicherheitsstufen (z.B. `['auth', 'admin']`).
### Verfügbare Middlewares
- `auth`: Stellt sicher, dass die Session `user_logged_in` aktiv ist. Leitet sonst zum Login um.
- `admin`: Stellt sicher, dass die Session `is_admin` wahr ist. Gibt sonst "Access Denied" aus.
---
## 🏛️ 3. Der Model-Layer (Datenabstraktion)
Alle Models erben von `MVC\Core\Model`. Dies gibt ihnen Zugriff auf mächtige Standardmethoden:
### CRUD-Operationen
- `Model::all()`: Gibt alle Datensätze der Tabelle zurück.
- `Model::find($id)`: Sucht einen Datensatz primär über die ID.
- `Model::where($sql, ...$params)`: Filtert Datensätze mit Prepared Statements.
- `Model::insert($data)`: Erwartet ein assoziatives Array (z.B. `['NAME' => 'Max']`).
- `Model::update($data, $where, ...$whereParams)`: Aktualisiert Felder basierend auf einer Bedingung.
- `Model::delete($where, ...$params)`: Löscht Datensätze.
- `Model::query($sql, ...$params)`: Ermöglicht komplexe, manuelle SQL-Abfragen.
### 💡 Besonderheit: Statische Bindung
In den Models wird die Tabelle über `protected static $table` definiert. Die Basisklasse nutzt `static::`, um immer auf die Tabelle des Kind-Models zuzugreifen.
---
## 🎮 4. Controller & AJAX (Die Logik)
Controller fungieren als Vermittler. Sie verarbeiten sowohl klassische Seitenaufrufe als auch AJAX-Requests.
### Seiten rendern
```php
return $this->render('view_name', ['key' => 'value']);
```
### JSON-Antworten (für AJAX)
Für moderne Oberflächen, die Daten nachladen oder umschalten ohne Refresh:
```php
return $this->json(['success' => true, 'data' => $result]);
```
---
## 🧱 5. Das modulare Block-Layout
Das Layout ist in "Blöcke" unterteilt, die in der `index.php` befüllt werden.
### Blöcke setzen
```php
$layout->setBlock('header', $html_content);
$layout->setBlock('sidebar', $sidebar_html);
```
### Blöcke in der View nutzen (Layout-Template)
In `Layout/Templates/main.php` werden die Blöcke mit `$this->getBlock('name')` ausgegeben.
---
## 🛡️ 6. Error-Handling & Sicherheit
### Zentrales Catch-System
Die gesamte Applikation läuft in einem `try-catch` Block.
- Tritt ein Fehler (Exception) auf, wird dieser im System-Log gespeichert.
- **Admins** sehen den "Stacktrace" (Pfad des Fehlers) zur schnellen Behebung.
- **Benutzer** sehen eine generische, freundliche Fehlermeldung.
### SQL-Injection Schutz
Durch die konsequente Nutzung von `Model::where`, `Model::insert` etc., werden automatisch **Prepared Statements** genutzt. SQL-Injections sind dadurch nahezu ausgeschlossen.
### XSS-Schutz
Variablen in der View sollten **immer** mit `htmlspecialchars()` ausgegeben werden:
```html
<p><?= htmlspecialchars($user_name) ?></p>
```
---
## 🔍 7. Besonderheiten & Tipps
- **Namespace-Beachtung**: Da wir Namespaces nutzen (`MVC\Controller`), müssen globale PHP-Funktionen oder Klassen aus dem `src/utils` Ordner mit einem Backslash aufgerufen werden (z.B. `\db_connect()` oder `\getSpecificData()`).
- **Globaler State**: Variablen aus der `config.php` (wie `$Berechtigungen`) müssen in Controllern oft via `global $variable;` bekannt gemacht werden, bevor sie an Models übergeben werden.
- **Post-Redirect-Get**: Nach dem Speichern von Daten (`POST`) im Controller immer ein `header("Location: ...")` ausführen, um doppelte Einsendungen beim Neuladen zu verhindern.
- **Statische Files**: Bilder, CSS und JS gehören in den Ordner `WEBROOT/static/`.
---
## 🚀 Modul-Generator
Nutze das Script im Hauptverzeichnis für schnelle Ergebnisse:
```bash
php create_module.php mein_name
```
Dieses erstellt automatisch Controller und View nach den oben genannten Standards.
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class CompanyReport extends Model {
protected static $table = "Firmenberichte";
public static function getByDateRange($start, $end) {
$sql = "SELECT `DATUM`, `PROZESS_1`, `PROZESS_2`, `PROZESS_3`, `PROZESS_4` FROM Firmenberichte WHERE `DATUM` BETWEEN ? AND ?";
return self::query($sql, $start, $end)->fetch_all(MYSQLI_ASSOC);
}
public static function getWochen() {
self::query("SET @row := 0");
$sql = "SELECT MIN(DATUM) AS start_date, MAX(DATUM) AS end_date FROM (SELECT DATUM, DATE_SUB(DATUM, INTERVAL (@row := @row + 1) DAY) AS grp FROM Firmenberichte ORDER BY DATUM) AS t GROUP BY grp ORDER BY start_date";
return self::query($sql)->fetch_all(MYSQLI_ASSOC);
}
public static function getTotalOvertime() {
$res = self::query("SELECT SUM(OVERTIME) AS summe FROM Firmenberichte");
return intval($res->fetch_object()->summe ?? 0);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class Documentation extends Model {
protected static $table = "Dokumentation";
public static function search($query, $page = 1, $limit = 5) {
$offset = ($page - 1) * $limit;
$search = "%$query%";
$countRes = \DatabaseShow(self::$table, "COUNT(*) as total", "TITEL LIKE ? OR INHALT LIKE ? OR KATEGORIE LIKE ?", $search, $search, $search);
$total = $countRes[0]['total'] ?? 0;
$sql = "SELECT * FROM Dokumentation WHERE TITEL LIKE ? OR INHALT LIKE ? OR KATEGORIE LIKE ? ORDER BY ERSTELLT_AM DESC LIMIT ? OFFSET ?";
$result = self::query($sql, $search, $search, $search, $limit, $offset);
$rows = $result->fetch_all(MYSQLI_ASSOC);
return [
'rows' => $rows,
'total' => $total,
'pages' => ceil($total / $limit),
'current_page' => $page
];
}
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class Domain extends Model {
protected static $table = "Domains";
}
+43
View File
@@ -0,0 +1,43 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class Log extends Model {
protected static $table = "logs";
public static function getFiltered($websiteFilter, $devIpsSql, $filter) {
switch ($filter) {
case 'today':
$sql = "SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`, `FIRST_REQUEST`, `WEBSITE` FROM logs WHERE DATE(FIRST_REQUEST) = CURDATE() AND $websiteFilter AND CLIENT_IP NOT IN ($devIpsSql) ORDER BY FIRST_REQUEST DESC";
break;
case 'counterperip':
$sql = "SELECT CLIENT_IP, LAND, USER_AGENT, SUM(counter) AS gesamt_counter FROM logs WHERE $websiteFilter AND CLIENT_IP NOT IN ($devIpsSql) GROUP BY CLIENT_IP ORDER BY gesamt_counter DESC";
break;
case 'node1':
case 'node2':
case 'node3':
case 'node4':
$sql = "SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`, `FIRST_REQUEST`, `WEBSITE` FROM logs WHERE `SERVER_IP` = ? AND $websiteFilter ORDER BY `FIRST_REQUEST` DESC";
$res = self::query($sql, $filter);
return $res->fetch_all(MYSQLI_ASSOC);
default:
$sql = "SELECT `CLIENT_IP`, `LAND`, `REQUEST_URL`, `COUNTER`, `FIRST_REQUEST`, `WEBSITE` FROM logs WHERE $websiteFilter AND CLIENT_IP NOT IN ($devIpsSql) ORDER BY FIRST_REQUEST DESC";
}
$res = self::query($sql);
return $res->fetch_all(MYSQLI_ASSOC);
}
public static function getChartData($websiteFilter = null) {
$where = $websiteFilter ? "WHERE $websiteFilter" : "";
$sql = "SELECT DATE(FIRST_REQUEST) as tag, COUNT(*) as anzahl FROM logs $where GROUP BY DATE(FIRST_REQUEST) ORDER BY DATE(FIRST_REQUEST)";
return self::query($sql)->fetch_all(MYSQLI_ASSOC);
}
public static function getNodeChartData($node) {
$sql = "SELECT DATE(FIRST_REQUEST) as tag, COUNT(*) as anzahl FROM logs WHERE SERVER_IP = ? GROUP BY DATE(FIRST_REQUEST)";
return self::query($sql, $node)->fetch_all(MYSQLI_ASSOC);
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class Overtime extends Model {
protected static $table = "Ueberstunden";
public static function getSumByReason($reason) {
$res = self::query("SELECT SUM(MINUTEN) AS summe FROM Ueberstunden WHERE GRUND = ?", $reason);
return intval($res->fetch_object()->summe ?? 0);
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class SchoolReport extends Model {
protected static $table = "Berufsschulberichte";
public static function allWithFK() {
global $Berufsschulberichte;
return \DatabaseShowWithFK(self::$table, $Berufsschulberichte);
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class User extends Model {
protected static $table = "Benutzer";
public static function getByName($name) {
return self::where("NAME = ?", $name);
}
public static function isAdmin($userId) {
$user = self::find($userId);
return ($user['ADMIN'] ?? 0) == 1;
}
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace MVC\Model;
use MVC\Core\Model;
class Variable extends Model {
protected static $table = "Variablen";
public static function getByName($name) {
return self::where("VARIABLENNAME = ?", $name)[0] ?? null;
}
public static function toggle($name) {
$var = self::getByName($name);
if ($var) {
$newValue = ($var['WERT'] === "ON") ? "OFF" : "ON";
return self::update(['WERT' => $newValue], "VARIABLENNAME = ?", $name);
}
return false;
}
}
+341
View File
@@ -0,0 +1,341 @@
<style>
.api-tester-container {
width: 100%;
max-width: 1000px;
margin: 0 auto;
background-color: var(--card-bg);
padding: 25px;
border-radius: 12px;
border: 1px solid var(--card-border);
box-sizing: border-box;
}
.api-tester-container h2 {
margin-top: 0;
margin-bottom: 20px;
color: var(--btn-bg);
border-bottom: 1px solid var(--card-border);
padding-bottom: 12px;
display: block;
}
.tester-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
}
.tester-form-group {
margin-bottom: 16px;
}
.tester-form-group label {
display: block;
margin-bottom: 6px;
font-weight: bold;
font-size: 0.9rem;
}
.tester-input,
.tester-textarea,
select {
width: 100%;
padding: 10px;
background-color: var(--input-bg);
border: 1px solid var(--input-border);
color: var(--input-text);
border-radius: 6px;
box-sizing: border-box;
font-size: 0.9rem;
}
.tester-textarea {
min-height: 120px;
resize: vertical;
font-family: Consolas, monospace;
}
.tester-btn-send {
width: 100%;
background-color: var(--btn-bg);
color: white;
border: none;
border-radius: 8px;
padding: 13px;
font-weight: bold;
cursor: pointer;
transition: 0.2s;
margin-top: 5px;
}
.tester-btn-send:hover {
opacity: 0.9;
transform: translateY(-1px);
}
#tester-response-container {
margin-top: 25px;
background-color: var(--input-bg);
border: 1px solid var(--card-border);
border-radius: 10px;
padding: 15px;
min-height: 100px;
overflow-x: auto;
}
#tester-output-content {
white-space: pre-wrap;
font-family: Consolas, monospace;
font-size: 0.85rem;
margin: 0;
color: var(--text);
}
.tester-badge {
display: inline-block;
padding: 5px 10px;
border-radius: 5px;
font-size: 0.8rem;
font-weight: bold;
margin-bottom: 12px;
}
.tester-status-200 {
background-color: #198754;
color: white;
}
.tester-status-error {
background-color: #dc3545;
color: white;
}
.tester-status-warning {
background-color: #ffc107;
color: black;
}
.hidden {
display: none !important;
}
.tester-row {
display: flex;
gap: 10px;
align-items: center;
}
.tester-checkbox {
display: flex;
align-items: center;
gap: 6px;
white-space: nowrap;
margin-top: 8px;
}
.tester-small-btn {
background: transparent;
border: 1px solid var(--input-border);
color: var(--text);
padding: 6px 10px;
border-radius: 6px;
cursor: pointer;
}
.tester-small-btn:hover {
background: rgba(255, 255, 255, 0.05);
}
.tester-response-info {
margin-bottom: 12px;
font-size: 0.85rem;
opacity: 0.8;
}
@media (max-width: 700px) {
.tester-grid {
grid-template-columns: 1fr;
}
.tester-row {
flex-direction: column;
align-items: stretch;
}
}
</style>
<div class="api-tester-container">
<h2>🛠️ API Tester</h2>
<div class="tester-form-group">
<label for="endpoint">API Endpunkt</label>
<select id="endpoint" class="tester-input" onchange="checkEndpoint()">
<?php foreach ($apiOptions as $opt): ?>
<option value="<?= htmlspecialchars($opt) ?>"><?= htmlspecialchars($opt) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="tester-grid">
<div class="tester-form-group">
<label for="method">HTTP Methode</label>
<select id="method" class="tester-input">
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="PATCH">PATCH</option>
<option value="OPTIONS">OPTIONS</option>
</select>
</div>
<div class="tester-form-group" id="function-group">
<label for="function-header">Function Header</label>
<input type="text" id="function-header" class="tester-input" placeholder="z.B. IPs, Ueberstunden">
</div>
</div>
<div class="tester-form-group">
<label for="token">Authorization Token</label>
<div class="tester-row">
<input type="text" id="token" class="tester-input" value="<?= htmlspecialchars($defaultToken) ?>">
<label class="tester-checkbox">
<input type="checkbox" id="send-token" checked>
Mitsenden
</label>
</div>
</div>
<div class="tester-form-group">
<label for="custom-headers">Zusätzliche Header (JSON)</label>
<textarea id="custom-headers" class="tester-textarea" placeholder='{"X-Test": "123", "Client": "Frontend"}'></textarea>
</div>
<div class="tester-form-group" id="json-body-group">
<label for="json-body">JSON Body</label>
<textarea id="json-body" class="tester-textarea" placeholder='{"test": true}'></textarea>
</div>
<div class="tester-form-group hidden" id="file-group">
<label for="files">Dateien Upload</label>
<input type="file" id="files" class="tester-input" multiple>
</div>
<div class="tester-grid">
<button class="tester-btn-send" onclick="sendApiRequest()">Anfrage senden 🚀</button>
<button class="tester-btn-send" onclick="clearResponse()">Ausgabe leeren 🧹</button>
</div>
<div id="tester-response-container">
<div style="text-align:center; opacity:0.7; padding:15px;">Bereit für Anfragen.</div>
</div>
</div>
<script>
function checkEndpoint() {
const endpoint = document.getElementById('endpoint').value;
const fileGroup = document.getElementById('file-group');
const functionGroup = document.getElementById('function-group');
const jsonBodyGroup = document.getElementById('json-body-group');
const methodSelect = document.getElementById('method');
fileGroup.classList.add('hidden');
functionGroup.classList.remove('hidden');
jsonBodyGroup.classList.remove('hidden');
if (endpoint.includes('upload.php')) {
fileGroup.classList.remove('hidden');
jsonBodyGroup.classList.add('hidden');
methodSelect.value = 'POST';
}
if (endpoint.includes('get.php')) {
methodSelect.value = 'GET';
}
}
function clearResponse() {
document.getElementById('tester-response-container').innerHTML = `
<div style="text-align:center; opacity:0.7; padding:15px;">Ausgabe geleert.</div>
`;
}
async function sendApiRequest() {
const endpoint = document.getElementById('endpoint').value;
const method = document.getElementById('method').value;
const token = document.getElementById('token').value;
const functionHeader = document.getElementById('function-header').value;
const customHeadersInput = document.getElementById('custom-headers').value;
const jsonBodyInput = document.getElementById('json-body').value;
const fileInput = document.getElementById('files');
const sendToken = document.getElementById('send-token').checked;
const responseContainer = document.getElementById('tester-response-container');
responseContainer.innerHTML = `<div style="text-align:center; padding:15px;">Anfrage läuft...</div>`;
let headers = {};
if (sendToken && token.trim() !== '') headers['Authorization'] = token;
if (functionHeader.trim() !== '') headers['Function'] = functionHeader;
if (customHeadersInput.trim() !== '') {
try {
const customHeaders = JSON.parse(customHeadersInput);
headers = { ...headers, ...customHeaders };
} catch (e) {
responseContainer.innerHTML = `<div style="color:#dc3545; padding:15px;">Fehlerhafte Header JSON Struktur.</div>`;
return;
}
}
let options = { method: method, headers: headers };
if (endpoint.includes('upload.php') && fileInput.files.length > 0) {
const formData = new FormData();
for (let i = 0; i < fileInput.files.length; i++) formData.append('files[]', fileInput.files[i]);
options.body = formData;
} else {
if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(method) && jsonBodyInput.trim() !== '') {
try {
JSON.parse(jsonBodyInput);
headers['Content-Type'] = 'application/json';
options.body = jsonBodyInput;
} catch (e) {
responseContainer.innerHTML = `<div style="color:#dc3545; padding:15px;">Fehlerhafte JSON Body Struktur.</div>`;
return;
}
}
}
const startedAt = performance.now();
try {
const response = await fetch(endpoint, options);
const duration = (performance.now() - startedAt).toFixed(0);
const status = response.status;
const rawText = await response.text();
let resultText = rawText;
try {
const json = JSON.parse(rawText);
resultText = JSON.stringify(json, null, 2);
} catch (e) {}
let badgeClass = status >= 200 && status < 300 ? 'tester-status-200' : (status >= 300 && status < 400 ? 'tester-status-warning' : 'tester-status-error');
responseContainer.innerHTML = `
<div class="tester-badge ${badgeClass}">Status: ${status}</div>
<div class="tester-response-info">⏱️ ${duration} ms</div>
<button class="tester-small-btn" onclick="copyResponse()">Antwort kopieren</button>
<pre id="tester-output-content"></pre>
`;
document.getElementById('tester-output-content').textContent = resultText;
} catch (error) {
responseContainer.innerHTML = `<div style="color:#dc3545; padding:15px;">Fehler: ${error.message}</div>`;
}
}
function copyResponse() {
const content = document.getElementById('tester-output-content');
if (!content) return;
navigator.clipboard.writeText(content.textContent);
alert('Antwort kopiert.');
}
checkEndpoint();
</script>
+72
View File
@@ -0,0 +1,72 @@
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
<canvas id="logChart" width="600" height="400"></canvas>
<script>
const ctx = document.getElementById('logChart').getContext('2d');
const logChart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php echo json_encode($labels); ?>,
datasets: [{
label: 'Logs pro Tag',
data: <?php echo json_encode($data); ?>,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: true,
tension: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Logs pro Tag'
},
legend: {
display: true,
position: 'top'
},
zoom: {
pan: {
enabled: true,
mode: 'x',
},
zoom: {
wheel: {
enabled: true,
},
mode: 'x',
}
}
},
interaction: {
mode: 'index',
intersect: false
},
scales: {
x: {
title: {
display: true,
text: 'Datum'
}
},
y: {
min: 0,
max: 100,
title: {
display: true,
text: 'Anzahl Logs'
},
ticks: {
stepSize: 20
},
beginAtZero: true
}
}
}
});
</script>
+115
View File
@@ -0,0 +1,115 @@
<style>
.debug-table-container {
background: #252525;
border-radius: 8px;
padding: 0;
margin-top: 20px;
overflow-x: auto;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
table {
width: 100%;
border-collapse: collapse;
color: #ccc;
white-space: nowrap;
}
th {
background: #333;
text-align: left;
padding: 15px 12px;
border-bottom: 2px solid #3498db;
color: #3498db;
text-transform: uppercase;
font-size: 11px;
letter-spacing: 1px;
position: sticky;
top: 0;
z-index: 10;
}
td {
padding: 10px 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
font-size: 13px;
}
tr:nth-child(even) {
background: rgba(255, 255, 255, 0.02);
}
tr:hover {
background: rgba(52, 152, 219, 0.1);
color: #fff;
}
td:first-child,
th:first-child {
position: sticky;
left: 0;
background: #252525;
z-index: 5;
border-right: 1px solid rgba(255, 255, 255, 0.1);
}
th:first-child {
z-index: 11;
background: #333;
}
.empty-note {
padding: 40px;
text-align: center;
color: #777;
font-style: italic;
}
</style>
<h2 style="display: flex; justify-content: space-between; align-items: center;">
<span>📊 Berichtte-Vorschau:</span>
<div>
<a href="?service=<?= htmlspecialchars($selectedService) ?>&mode=fk">
<button <?= $mode === 'fk' ? 'style="background:#3498db;color:white;"' : '' ?>>
Berufsschulberichte
</button>
</a>
<a href="?service=<?= htmlspecialchars($selectedService) ?>&mode=normal">
<button <?= $mode === 'normal' ? 'style="background:#3498db;color:white;"' : '' ?>>
Arbeitsberichte
</button>
</a>
</div>
</h2>
<?php if ($count > 0 && is_array($displayData[0])): ?>
<div class="debug-table-container">
<table>
<thead>
<tr>
<?php foreach (array_keys($displayData[0]) as $column): ?>
<th><?= htmlspecialchars($column) ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($displayData as $row): ?>
<tr>
<?php foreach ($row as $key => $cell): ?>
<td><?= htmlspecialchars($cell ?? '-') ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="debug-table-container">
<div class="empty-note">
Keine tabellarischen Daten gefunden.
</div>
</div>
<?php endif; ?>
@@ -0,0 +1,56 @@
<div class="content-box">
<h2>Ausbildungsberichte PDF erstellen</h2>
<form method="post" class="overtime-container">
<label for="start_date">Von:</label>
<input type="date" name="start_date" id="start_date" value="<?= htmlspecialchars($startDate) ?>">
<label for="end_date">Bis:</label>
<input type="date" name="end_date" id="end_date" value="<?= htmlspecialchars($endDate) ?>">
<button type="submit" name="generate_pdf">PDF erstellen</button>
</form>
<?php if ($pdfFile): ?>
<div class="overtime-result">
<?= htmlspecialchars(basename($pdfFile)) ?> erfolgreich erstellt!
</div>
<?php elseif(isset($_POST['generate_pdf'])): ?>
<div class="overtime-result negative">
Keine Berichte im gewählten Zeitraum gefunden.
</div>
<?php endif; ?>
<?php if(!empty($wochenArray)): ?>
<div class="wochen-liste">
<h3>Verfügbare Wochenabschnitte:</h3>
<ul>
<?php
foreach($wochenArray as $woche):
$pdfName = 'ausbildungsnachweis_' . $woche['start_date'] . '-' . $woche['end_date'] . '.pdf';
$pdfPath = (new \getSpecificData())->getDocumentRoot() . '/static/' . $pdfName;
$exists = file_exists($pdfPath);
?>
<li>
<code><?= htmlspecialchars($woche['start_date']) ?></code> bis
<code><?= htmlspecialchars($woche['end_date']) ?></code>
<?php if($exists): ?>
<span style="color:green;">(PDF vorhanden)</span>
<a href="<?= htmlspecialchars('/static/' . $pdfName) ?>" download class="btn btn-success">
Download
</a>
<?php else: ?>
<span style="color:red;">(noch keine PDF)</span>
<form method="post" style="display:inline;">
<input type="hidden" name="start_date" value="<?= htmlspecialchars($woche['start_date']) ?>">
<input type="hidden" name="end_date" value="<?= htmlspecialchars($woche['end_date']) ?>">
<button type="submit" name="generate_pdf" class="btn btn-primary">
PDF erzeugen
</button>
</form>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
</div>
+109
View File
@@ -0,0 +1,109 @@
<h2>System & Client Info</h2>
<?php foreach ($groupedData as $groupName => $fields): ?>
<div class="group-container">
<div class="group-header"><?= htmlspecialchars($groupName) ?> <span class="arrow">▸</span></div>
<ul class="info-list group-content">
<?php foreach ($fields as $field => $value): ?>
<li>
<span class="info-key"><?= htmlspecialchars($field) ?>:</span>
<span class="info-value">
<?php
if (is_array($value)) $value = implode(', ', $value);
echo htmlspecialchars($value ?? '');
?>
</span>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endforeach; ?>
<script>
document.querySelectorAll('.group-header').forEach(header => {
header.addEventListener('click', () => {
const content = header.nextElementSibling;
content.classList.toggle('open');
header.classList.toggle('open');
});
});
</script>
<style>
.group-container {
margin-bottom: 15px;
border: 1px solid var(--card-border);
border-radius: 6px;
overflow: hidden;
}
.group-header {
background-color: var(--card-bg);
padding: 10px 15px;
font-weight: bold;
cursor: pointer;
user-select: none;
display: flex;
justify-content: space-between;
align-items: center;
}
.group-header:hover {
background: rgba(0, 0, 0, 0.05);
}
body.dark-mode .group-header:hover {
background: rgba(255, 255, 255, 0.08);
}
.group-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
margin: 0;
padding: 0 15px;
}
.group-content.open {
max-height: 2000px;
padding: 10px 15px;
}
.arrow {
transition: transform 0.3s ease;
}
.group-header.open .arrow {
transform: rotate(90deg);
}
.info-list li {
padding: 5px 0;
display: flex;
flex-wrap: wrap;
border-bottom: 1px solid var(--card-border);
}
.info-list li:last-child {
border-bottom: none;
}
.info-key {
font-weight: bold;
width: 180px;
}
.info-value {
flex: 1;
word-break: break-word;
}
body.dark-mode .group-header {
background-color: var(--card-bg);
color: var(--text);
}
body.dark-mode .info-list li {
border-bottom: 1px solid #333;
}
</style>
+115
View File
@@ -0,0 +1,115 @@
<div class="documentation-container">
<h2>📚 Projekt-Dokumentation</h2>
<div class="search-bar">
<form method="GET">
<input type="hidden" name="service" value="documentation">
<input type="text" name="q" value="<?= htmlspecialchars($query) ?>" placeholder="Suchen...">
<button type="submit">Suchen</button>
</form>
</div>
<div class="doc-list">
<?php if (empty($docs)): ?>
<p>Keine Einträge gefunden.</p>
<?php else: ?>
<?php foreach ($docs as $doc): ?>
<div class="doc-item">
<span class="category-badge"><?= htmlspecialchars($doc['KATEGORIE']) ?></span>
<h3><?= htmlspecialchars($doc['TITEL']) ?></h3>
<p><?= nl2br(htmlspecialchars($doc['INHALT'])) ?></p>
<small>Erstellt am: <?= date('d.m.Y H:i', strtotime($doc['ERSTELLT_AM'])) ?></small>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<?php if ($pages > 1): ?>
<div class="pagination">
<?php for ($i = 1; $i <= $pages; $i++): ?>
<a href="?service=documentation&q=<?= urlencode($query) ?>&page=<?= $i ?>"
class="<?= $i === $currentPage ? 'active' : '' ?>">
<?= $i ?>
</a>
<?php endfor; ?>
</div>
<?php endif; ?>
</div>
<style>
.documentation-container {
max-width: 800px;
margin: 0 auto;
}
.search-bar {
margin-bottom: 25px;
}
.search-bar form {
display: flex;
gap: 10px;
}
.search-bar input {
flex: 1;
padding: 10px;
border-radius: 6px;
border: 1px solid var(--input-border);
background: var(--input-bg);
color: var(--input-text);
}
.doc-item {
background: var(--card-bg);
border: 1px solid var(--card-border);
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
position: relative;
}
.category-badge {
position: absolute;
top: 15px;
right: 15px;
background: var(--btn-bg);
color: white;
padding: 4px 10px;
border-radius: 15px;
font-size: 0.75rem;
font-weight: bold;
}
.doc-item h3 {
margin-top: 0;
color: var(--btn-bg);
}
.doc-item p {
line-height: 1.6;
}
.pagination {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 30px;
}
.pagination a {
display: inline-block;
padding: 8px 14px;
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 5px;
text-decoration: none;
color: var(--text);
}
.pagination a.active {
background: var(--btn-bg);
color: white;
border-color: var(--btn-bg);
}
</style>
+26
View File
@@ -0,0 +1,26 @@
<h2>Domain Verwaltung</h2>
<?php if ($statusMsg): ?>
<div class="status-msg"><?= htmlspecialchars($statusMsg) ?></div>
<?php endif; ?>
<div class="admin-grid">
<?php foreach ($domains as $domain): ?>
<form method="post" class="admin-card">
<input type="hidden" name="id" value="<?= $domain["ID"] ?>">
<label>Subdomain</label>
<input type="text" name="subdomain" value="<?= htmlspecialchars($domain["SUBDOMAIN"]) ?>">
<div style="margin-top:10px; display:flex; gap:10px;">
<button type="submit" name="save_domain" class="btn-save">Speichern</button>
<button type="submit" name="delete_domain" class="btn-delete">Löschen</button>
</div>
</form>
<?php endforeach; ?>
<form method="post" class="admin-card new-item">
<h3>Neu</h3>
<label>Subdomain</label>
<input type="text" name="subdomain" placeholder="z.B. subdomain.domain.net">
<button type="submit" name="add_domain" class="btn-add">Domain hinzufügen</button>
</form>
</div>
+106
View File
@@ -0,0 +1,106 @@
<div class="home-dashboard">
<div class="links-container">
<div class="link-group">
<h3 style="background-color: #007bff;">👤 Benutzerprofil</h3>
<div class="group-links" style="padding: 10px; color: inherit;">
<p style="margin: 5px 0;"><strong>Name:</strong> <code><?= htmlspecialchars($username) ?></code></p>
<?php if ($username != 'gast'): ?>
<p style="margin: 5px 0;"><strong>Nachname:</strong>
<code><?= htmlspecialchars($db_res[0]['NACHNAME'] ?? '') ?></code>
</p>
<p style="margin: 5px 0;"><strong>E-Mail:</strong>
<code><?= htmlspecialchars($db_res[0]['EMAIL'] ?? '') ?></code>
</p>
<p style="margin: 5px 0;"><strong>Benutzerrolle:</strong>
<code><?= htmlspecialchars($db_res[0]['ROLLE'] ?? '') ?></code>
</p>
<p style="margin: 5px 0;"><strong>Home IP:</strong>
<code><?= htmlspecialchars($db_res[0]['HOME_IP'] ?? '') ?></code>
</p>
<?php endif ?>
</div>
</div>
<div class="link-group">
<h3 style="background-color: #28a745;">🛡️ Status & Rechte</h3>
<div class="group-links"
style="padding: 10px; display: flex; flex-direction: row; gap: 10px; flex-wrap: wrap;">
<?php if ((new \getSpecificData())->getIsAdmin()): ?>
<span
style="background: #dc3545; color: white; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Admin</span>
<?php endif; ?>
<?php if ((new \getSpecificData())->getIsSuperuser()): ?>
<span
style="background: #ffc107; color: #000; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Superuser</span>
<?php endif; ?>
<?php if (!(new \getSpecificData())->getIsSuperuser() && !(new \getSpecificData())->getIsAdmin()): ?>
<span
style="background: #6c757d; color: white; padding: 4px 10px; border-radius: 15px; font-size: 0.8rem; font-weight: bold;">Standard-Nutzer</span>
<?php endif; ?>
</div>
</div>
<div class="link-group">
<h3 style="background-color: #17a2b8;">ℹ️ System-Info</h3>
<div class="group-links" style="padding: 10px;">
<p style="margin: 5px 0;"><strong>Datum:</strong>
<code><?= date('d.m.Y') ?><br></code>
</p>
<p style="margin: 5px 0;"><strong>Session-Status:</strong>
<code>Aktiv</code>
</p>
<?php if ($is_admin): ?>
<p style="margin: 5px 0;"><strong>Client IP:</strong>
<code><?= htmlspecialchars((new \getSpecificData())->getClientIP()) ?></code>
</p>
<p style="margin: 5px 0;"><strong>Server IP:</strong>
<code><?= htmlspecialchars((new \getSpecificData())->getServerIP()) ?></code>
</p>
<p style="margin: 5px 0;"><strong>Geo IP:</strong>
<code><?= htmlspecialchars((new \getSpecificData())->getGeoIP((new \getSpecificData())->getClientIP())) ?></code>
</p>
<p style="margin: 5px 0;"><strong>Database IP:</strong>
<code><?= htmlspecialchars((new \getSpecificData())->getDatabase()) ?></code>
</p>
<p style="margin: 5px 0;"><strong>Wetter:</strong>
<code><?= htmlspecialchars((new \getSpecificData())->getWeather()['aktuell']) ?></code>
</p>
<?php endif ?>
</div>
</div>
</div>
</div>
<style>
/* Zusätzliche Inline-Styles für die Feinabstimmung in der home_info */
.home-dashboard {
animation: fadeIn 0.5s ease-in-out;
}
code {
background: rgba(0, 0, 0, 0.1);
padding: 2px 5px;
border-radius: 4px;
font-family: monospace;
}
body.dark-mode code {
background: rgba(255, 255, 255, 0.1);
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
+65
View File
@@ -0,0 +1,65 @@
<?php
if (!isset($linkButtons) || !is_array($linkButtons)) {
echo "<p>Keine Links konfiguriert.</p>";
return;
}
if (!isset($linkGroups) || !is_array($linkGroups)) {
echo "<p>Keine Link-Gruppen konfiguriert.</p>";
return;
}
?>
<div class="links-container">
<?php foreach ($linkGroups as $groupKey => $group): ?>
<?php
$groupLinks = array_filter($linkButtons, function($button) use ($groupKey, $isAdmin) {
if (($button['group'] ?? null) !== $groupKey) {
return false;
}
if (!empty($button['adminOnly']) && !$isAdmin) {
return false;
}
return true;
});
if (empty($groupLinks)) {
continue;
}
$color = htmlspecialchars($group['color']);
?>
<div class="link-group">
<h3 style="background-color: <?= $color ?>;">
<?= htmlspecialchars($group['label']) ?>
</h3>
<div class="group-links">
<?php foreach ($groupLinks as $button):
$target = !empty($button['newTab']) ? '_blank' : '_self';
?>
<a href="<?= htmlspecialchars($button['url']) ?>"
target="<?= $target ?>"
<?= $target === '_blank' ? 'rel="noopener noreferrer"' : '' ?>>
<button class="link-button"
style="
border-color: <?= $color ?>;
background-color: <?= $color ?>;
">
<?= htmlspecialchars($button['label']) ?>
</button>
</a>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
+41
View File
@@ -0,0 +1,41 @@
<h1>📊 Logs</h1>
<form method="GET" action="index.php">
<input type="hidden" name="service" value="<?= htmlspecialchars($serviceName) ?>">
<select name="filter" onchange="this.form.submit()">
<?php
$options = ['alle','today','node1','node2','node3','node4','counterperip'];
foreach ($options as $opt) {
$sel = ($filter === $opt) ? 'selected' : '';
echo "<option value='$opt' $sel>$opt</option>";
}
?>
</select>
</form>
<br>
<?php if (!$daten): ?>
<b>Keine Daten gefunden</b>
<?php else: ?>
<div style="overflow-x:auto;">
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse:collapse;width:100%;">
<tr>
<?php foreach (array_keys($daten[0]) as $key): ?>
<th><?= htmlspecialchars($key) ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($daten as $row): ?>
<tr>
<?php foreach ($row as $val): ?>
<td><?= htmlspecialchars($val ?? '') ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
+57
View File
@@ -0,0 +1,57 @@
<button onclick="printFiles()">Alle Dateien drucken</button>
<div class="print-container">
<?php foreach ($files as $file):
$url = "static/" . rawurlencode($file);
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
?>
<div class="print-page">
<?php if (in_array($ext, ['png','jpg','jpeg','webp'])): ?>
<img src='<?= $url ?>'>
<?php elseif ($ext === "pdf"): ?>
<embed src='<?= $url ?>' type='application/pdf'>
<?php else: ?>
<p><?= htmlspecialchars($file) ?> kann nicht direkt gedruckt werden.</p>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<script>
function printFiles() {
window.print();
}
</script>
<style>
.print-page {
width: 100%;
height: 100vh;
page-break-after: always;
}
.print-page img {
max-width: 100%;
}
.print-page embed {
width: 100%;
height: 100vh;
}
@media print {
body * {
visibility: hidden;
}
.print-container,
.print-container * {
visibility: visible;
}
.print-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
}
</style>
+105
View File
@@ -0,0 +1,105 @@
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
<canvas id="logChart" width="900" height="500"></canvas>
<script>
const ctx = document.getElementById('logChart').getContext('2d');
const logChart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php echo json_encode($allLabels); ?>,
datasets: [{
label: 'Gesamt',
data: <?php echo json_encode($finalTotalData); ?>,
borderColor: 'rgb(255, 0, 0)',
backgroundColor: 'rgba(0, 0, 0, 0.2)',
fill: false,
tension: 0
},
{
label: 'Node1',
data: <?php echo json_encode($finalNodeData['node1']); ?>,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: false,
tension: 0,
hidden: true,
},
{
label: 'Node2',
data: <?php echo json_encode($finalNodeData['node2']); ?>,
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
fill: false,
tension: 0,
hidden: true,
},
{
label: 'Node3',
data: <?php echo json_encode($finalNodeData['node3']); ?>,
borderColor: 'rgba(255, 206, 86, 1)',
backgroundColor: 'rgba(255, 206, 86, 0.2)',
fill: false,
tension: 0,
hidden: true,
},
{
label: 'Node4',
data: <?php echo json_encode($finalNodeData['node4']); ?>,
borderColor: 'rgba(54, 162, 235, 1)',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
fill: false,
tension: 0,
hidden: true,
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Logs pro Tag nach Node und Gesamt'
},
legend: {
display: true,
position: 'top'
},
zoom: {
pan: {
enabled: true,
mode: 'x'
},
zoom: {
wheel: {
enabled: true
},
mode: 'x'
}
}
},
interaction: {
mode: 'index',
intersect: false
},
scales: {
x: {
title: {
display: true,
text: 'Datum'
}
},
y: {
beginAtZero: true,
title: {
display: true,
text: 'Anzahl Logs'
}
}
}
}
});
</script>
+193
View File
@@ -0,0 +1,193 @@
<div class="content">
<?php if (!$loggedIn): ?>
<div class="login-container">
<div class="login-box">
<form method="post">
<h2>🔐 Login</h2>
<?php if($error): ?>
<div class="status-msg" style="background:#dc3545; color:#fff;"><?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>
<input type="password" name="password" placeholder="Passwort" required>
<button type="submit">Einloggen</button>
</form>
</div>
</div>
<?php else: ?>
<div class="content">
<h2>Seitenverwaltung</h2>
<form method="post">
<button type="submit" name="logout" id="logoutSiteButton">Logout</button>
</form>
<?php if($message): ?><div class="status-msg"><?= htmlspecialchars($message) ?></div><?php endif; ?>
<form method="post">
<!-- Sidebar Gruppen -->
<h2>📦 Sidebar Gruppen
<button type="button" class="btn-add" onclick="addNew('serviceGroup')">+ Neue Gruppe</button>
</h2>
<div class="admin-grid" id="container-serviceGroup">
<?php foreach ($serviceGroups as $id => $group): ?>
<div class="admin-card">
<span class="badge">ID: <?= htmlspecialchars($id) ?></span>
<input type="text" name="serviceGroups[<?= $id ?>][label]"
value="<?= htmlspecialchars($group['label']) ?>" placeholder="Anzeigename">
<label>
<input type="checkbox" name="serviceGroups[<?= $id ?>][defaultOpen]"
<?= ($group['defaultOpen'] ?? false) ? 'checked' : '' ?>>
Offen
</label>
</div>
<?php endforeach; ?>
</div>
<!-- Sidebar Services -->
<h2>🖥 Sidebar Services
<button type="button" class="btn-add" onclick="addNew('service')">+ Neuer Service</button>
</h2>
<div class="admin-grid" id="container-service">
<?php foreach ($services as $id => $s): ?>
<div class="admin-card">
<span class="badge">Datei: <?= htmlspecialchars($id) ?>.php</span>
<input type="text" name="services[<?= $id ?>][name]" value="<?= htmlspecialchars($s['name']) ?>"
placeholder="Name">
<label>Sidebar-Gruppe:</label>
<select name="services[<?= $id ?>][targetGroup]">
<?php foreach ($serviceGroups as $gid => $g): ?>
<option value="<?= $gid ?>"
<?= (isset($g['services']) && in_array($id, $g['services'])) ? 'selected' : '' ?>>
<?= htmlspecialchars($g['label']) ?>
</option>
<?php endforeach; ?>
</select>
<label>
<input type="checkbox" name="services[<?= $id ?>][active]"
<?= ($s['active'] ?? false) ? 'checked' : '' ?>>
Aktiv
</label>
|
<label>
<input type="checkbox" name="services[<?= $id ?>][adminOnly]"
<?= ($s['adminOnly'] ?? false) ? 'checked' : '' ?>>
Nur Admins
</label>
</div>
<?php endforeach; ?>
</div>
<!-- Dashboard Kategorien -->
<h2>🎨 Dashboard Kategorien
<button type="button" class="btn-add" onclick="addNew('linkGroup')">+ Neue Kategorie</button>
</h2>
<div class="admin-grid" id="container-linkGroup">
<?php foreach ($linkGroups as $id => $lg): ?>
<div class="admin-card">
<span class="badge">ID: <?= htmlspecialchars($id) ?></span>
<input type="text" name="linkGroups[<?= $id ?>][label]"
value="<?= htmlspecialchars($lg['label']) ?>" placeholder="Gruppen-Label">
<label>Farbe:</label>
<input type="color" name="linkGroups[<?= $id ?>][color]"
value="<?= $lg['color'] ?? '#3498db' ?>">
<label>
<input type="checkbox" name="linkGroups[<?= $id ?>][defaultOpen]"
<?= ($lg['defaultOpen'] ?? false) ? 'checked' : '' ?>>
Offen
</label>
</div>
<?php endforeach; ?>
</div>
<!-- Dashboard Kacheln -->
<h2>🔘 Dashboard Kacheln
<button type="button" class="btn-add" onclick="addNew('linkButton')">+ Neue Kachel</button>
</h2>
<div class="admin-grid" id="container-linkButton">
<?php foreach ($linkButtons as $key => $btn): ?>
<div class="admin-card">
<input type="text" name="linkButtons[<?= $key ?>][label]"
value="<?= htmlspecialchars($btn['label']) ?>" placeholder="Name">
<input type="text" name="linkButtons[<?= $key ?>][url]"
value="<?= htmlspecialchars($btn['url']) ?>" placeholder="URL">
<label>Dashboard Kategorie:</label>
<select name="linkButtons[<?= $key ?>][group]">
<?php foreach ($linkGroups as $id => $lg): ?>
<option value="<?= $id ?>" <?= ($btn['group'] == $id) ? 'selected' : '' ?>>
<?= htmlspecialchars($lg['label']) ?>
</option>
<?php endforeach; ?>
</select>
<div style="margin-top:5px;">
<label>
<input type="checkbox" name="linkButtons[<?= $key ?>][newTab]"
<?= ($btn['newTab'] ?? false) ? 'checked' : '' ?>>
Neuer Tab
</label>
|
<label>
<input type="checkbox" name="linkButtons[<?= $key ?>][adminOnly]"
<?= ($btn['adminOnly'] ?? false) ? 'checked' : '' ?>>
Nur Admins
</label>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="save-bar">
<button type="submit" name="save" class="btn-save">💾 Gesamte Konfiguration speichern</button>
</div>
</form>
</div>
<?php endif; ?>
</div>
<script>
function addNew(type) {
const container = document.getElementById('container-' + type);
const tempId = 'new_' + Date.now();
const card = document.createElement('div');
card.className = 'admin-card new-item';
let html = `<div><span class="badge">Neu hinzufügen</span></div>`;
if (type === 'serviceGroup') {
html +=
`<input type="text" name="serviceGroups[${tempId}][new_id]" placeholder="ID">
<input type="text" name="serviceGroups[${tempId}][label]" placeholder="Name">
<label><input type="checkbox" name="serviceGroups[${tempId}][defaultOpen]" checked> Ausgeklappt</label>`;
} else if (type === 'service') {
html += `<input type="text" name="services[${tempId}][new_id]" placeholder="Datei ohne .php">
<input type="text" name="services[${tempId}][name]" placeholder="Anzeigename">
<label>Gruppe:</label>
<select name="services[${tempId}][targetGroup]">
<?php foreach ($serviceGroups as $gid => $gl): ?>
<option value="<?= $gid ?>"><?= $gl['label'] ?></option>
<?php endforeach; ?>
</select>
<label><input type="checkbox" name="services[${tempId}][active]" checked> Aktiv</label>`;
} else if (type === 'linkGroup') {
html += `<input type="text" name="linkGroups[${tempId}][new_id]" placeholder="ID">
<input type="text" name="linkGroups[${tempId}][label]" placeholder="Label">
<input type="color" name="linkGroups[${tempId}][color]" value="#3498db">`;
} else if (type === 'linkButton') {
html += `<input type="text" name="linkButtons[${tempId}][label]" placeholder="Anzeigename">
<input type="text" name="linkButtons[${tempId}][url]" placeholder="https://...">
<label>Kategorie:</label>
<select name="linkButtons[${tempId}][group]">
<?php foreach ($linkGroups as $gid => $gl): ?>
<option value="<?= $gid ?>"><?= $gl['label'] ?></option>
<?php endforeach; ?>
</select>
<label><input type="checkbox" name="linkButtons[${tempId}][newTab]" checked> Tab</label>
| <label><input type="checkbox" name="linkButtons[${tempId}][adminOnly]"> Nur Admins</label>`;
}
card.innerHTML = html;
container.appendChild(card);
card.scrollIntoView({
behavior: 'smooth'
});
}
</script>
+40
View File
@@ -0,0 +1,40 @@
<h2>Datenbank Struktur</h2>
<form method="GET">
<input type="hidden" name="service" value="tabellen">
<label for="table">Tabelle auswählen:</label>
<select name="table" id="table" onchange="this.form.submit()">
<option value="">-- Bitte wählen --</option>
<?php foreach ($tables as $table): ?>
<option value="<?= htmlspecialchars($table) ?>" <?= ($selectedTable === $table) ? 'selected' : '' ?>>
<?= htmlspecialchars($table) ?>
</option>
<?php endforeach; ?>
</select>
</form>
<?php if ($selectedTable && !empty($structure)): ?>
<div class='table-container'>
<table class='db-table'>
<tr>
<th>Field</th>
<th>Type</th>
<th>Null</th>
<th>Key</th>
<th>Default</th>
<th>Extra</th>
</tr>
<?php foreach ($structure as $column): ?>
<tr>
<td><?= htmlspecialchars($column['Field']) ?></td>
<td><?= htmlspecialchars($column['Type']) ?></td>
<td><?= htmlspecialchars($column['Null']) ?></td>
<td><?= htmlspecialchars($column['Key']) ?></td>
<td><?= htmlspecialchars($column['Default'] ?? '') ?></td>
<td><?= htmlspecialchars($column['Extra']) ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
<?php endif; ?>
+90
View File
@@ -0,0 +1,90 @@
<div class="content">
<?php if (!$loggedIn): ?>
<div class="login-container">
<div class="login-box">
<form method="post">
<h2>🔐 Login</h2>
<?php if($error): ?>
<div class="status-msg" style="background:#dc3545; color:#fff;"><?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>
<input type="password" name="password" placeholder="Passwort" required>
<button type="submit">Einloggen</button>
</form>
</div>
</div>
<?php else: ?>
<h2>Benutzerverwaltung</h2>
<form method="post">
<button type="submit" name="logout" id="logoutSiteButton">Logout</button>
</form>
<?php if ($isAdmin): ?>
<div class="form-container">
<h3>Neuen Benutzer anlegen</h3>
<form method="POST" action="">
<div class="user-form-grid">
<input type="text" name="name" placeholder="Vorname" required>
<input type="text" name="nachname" placeholder="Nachname" required>
<input type="text" name="email" placeholder="E-Mail" required>
<input type="text" name="passwort" placeholder="Passwort" required>
<input type="text" name="rolle" placeholder="Rolle (z.B. User)">
<input type="text" name="home_ip" placeholder="Home IP">
<label class="checkbox-group">
<input type="checkbox" name="admin" value="1">
<span>Admin-Rechte</span>
</label>
</div>
<button type="submit" name="add_user" class="btn-submit">
Benutzer speichern
</button>
</form>
</div>
<?php endif; ?>
<div class="table-container">
<table class="user-table">
<thead>
<tr>
<th>Vorname</th>
<th>Nachname</th>
<th>E-Mail</th>
<?php if ($isAdmin): ?>
<th>Rolle</th>
<th>Admin</th>
<th>Home IP</th>
<th></th>
<?php endif; ?>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?= htmlspecialchars($user['NAME']) ?></td>
<td><?= htmlspecialchars($user['NACHNAME']) ?></td>
<td><?= htmlspecialchars($user['EMAIL']) ?></td>
<?php if ($isAdmin): ?>
<td><?= htmlspecialchars($user['ROLLE']) ?></td>
<td><?= htmlspecialchars($user['ADMIN']) ?></td>
<td><?= htmlspecialchars($user['HOME_IP']) ?></td>
<td>
<form method="POST" onsubmit="return confirm('Wirklich löschen?');">
<input type="hidden" name="delete_name" value="<?= htmlspecialchars($user['NAME']) ?>">
<input type="hidden" name="delete_nachname"
value="<?= htmlspecialchars($user['NACHNAME']) ?>">
<input type="hidden" name="delete_email" value="<?= htmlspecialchars($user['EMAIL']) ?>">
<button type="submit" name="delete_user" class="btn-delete">
Löschen
</button>
</form>
</td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
@@ -0,0 +1,29 @@
<div class="admin-grid">
<?php foreach ($variablen as $var): ?>
<div class="admin-card toggle-card">
<div class="toggle-header">
<strong><?= htmlspecialchars($var['ANZEIGENAME']) ?></strong>
</div>
<form method="post">
<input type="hidden" name="variablenname" value="<?= htmlspecialchars($var['VARIABLENNAME']) ?>">
<button type="submit" name="toggle_variable"
class="toggle-switch <?= $var['WERT'] === 'ON' ? 'active' : '' ?>">
<span class="toggle-slider"></span>
</button>
</form>
<div class="toggle-status">
Status:
<span class="badge">
<?= htmlspecialchars($var['WERT']) ?>
</span>
</div>
</div>
<?php endforeach; ?>
</div>
+45
View File
@@ -0,0 +1,45 @@
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom"></script>
<canvas id="logChart" width="600" height="400"></canvas>
<script>
const ctx = document.getElementById('logChart').getContext('2d');
const logChart = new Chart(ctx, {
type: 'line',
data: {
labels: <?php echo json_encode($labels); ?>,
datasets: [{
label: 'Wetter',
data: <?php echo json_encode($data); ?>,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: false,
tension: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: { display: true },
legend: { display: true, position: 'top' },
zoom: {
pan: { enabled: true, mode: 'x' },
zoom: { wheel: { enabled: true }, mode: 'x' }
}
},
interaction: { mode: 'index', intersect: false },
scales: {
x: { title: { display: true, text: 'Zeitraum' } },
y: {
min: -10,
max: 40,
title: { display: true, text: 'Temperatur in °C' },
ticks: { stepSize: 1 },
beginAtZero: true
}
}
}
});
</script>
+40
View File
@@ -0,0 +1,40 @@
<div class="arbeitsberichte-wrapper">
<div
style="background: rgba(150,150,150,0.05); padding: 25px; border-radius: 10px; margin-bottom: 25px; border: 1px solid rgba(150,150,150,0.2); border-left: 6px solid #007bff;">
<div style="margin-bottom: 20px;">
<span style="color: #888; font-size: 0.8rem; font-weight: bold; text-transform: uppercase;">Aktueller
Stand</span>
<h2 style="margin: 5px 0 0 0; font-size: 2rem; color: <?= $gesamt_minuten >= 0 ? '#28a745' : '#dc3545' ?>;">
<?= intdiv($gesamt_minuten, 60) ?>h <?= abs($gesamt_minuten % 60) ?>min
</h2>
</div>
<?php if (strtolower($username) == "bruno"): ?>
<form method="POST" style="display: flex; gap: 15px; flex-wrap: wrap; align-items: flex-end;">
<input type="hidden" name="add_overtime" value="1">
<div style="display: flex; flex-direction: column; gap: 5px;">
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Datum</label>
<input type="date" name="ot_date" value="<?= date('Y-m-d') ?>" required
style="padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
</div>
<div style="display: flex; flex-direction: column; gap: 5px;">
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Minuten Abbau</label>
<input type="number" name="ot_minutes" placeholder="480" required
style="width: 100px; padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
</div>
<div class="form-group">
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Grund</label>
<select name="ot_reason" required>
<option value="">Bitte wählen</option>
<option value="Abbau">Abbau</option>
<option value="Aufbau">Aufbau</option>
<option value="Anderes">Anderes</option>
</select>
</div>
<button type="submit"
style="background: #007bff; color: white; border: none; padding: 10px 20px; border-radius: 4px; font-weight: bold; cursor: pointer;">
Eintrag speichern
</button>
</form>
<?php endif ?>
</div>
</div>
+18
View File
@@ -0,0 +1,18 @@
<?php
spl_autoload_register(function ($class) {
$prefix = 'MVC\\';
$base_dir = __DIR__ . '/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
+262
View File
@@ -0,0 +1,262 @@
<?php
class getSpecificData {
public function getWeather() {
$url = "https://api.openweathermap.org/data/2.5/weather?q=Jena,DE&APPID=5bc3e1a438c58fca444c4370ac0517b2&units=metric";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
if(curl_errno($ch)) {
echo "cURL Fehler: " . curl_error($ch);
exit;
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$data = json_decode($response, true);
return [
'aktuell' => $data['main']['temp'],
'min' => $data['main']['temp_min'],
'max' => $data['main']['temp_max'],
'gefuehlt' => $data['main']['feels_like']
];
} else {
return "API Fehler. HTTP Code: " . $httpCode;
}
}
public function getUserAgent(): string {
return $_SERVER['HTTP_USER_AGENT'] ?? 'Unbekannt';
}
public function getRequestURL(): string {
return $_SERVER['REQUEST_URI'] ?? 'Unbekannt';
}
public function getCookie(string $name): ?string {
return $_COOKIE[$name] ?? 'Unbekannt';
}
public function getSessionID(): string {
return $session_id ?? 'Unbekannt ';
}
public function getServerPort(): string {
return $_SERVER['SERVER_PORT'] ?? 'Unbekannt';
}
public function getClientPort(): string {
return $_SERVER['REMOTE_PORT'] ?? 'Unbekannt';
}
public function getDocumentRoot(): string {
return $_SERVER['DOCUMENT_ROOT'] ?? 'Unbekannt';
}
public function getQuery(): string {
return $_SERVER['QUERY_STRING'] ?? 'Unbekannt';
}
public function getRequestMethod(): string {
return $_SERVER['REQUEST_METHOD'] ?? 'Unbekannt';
}
public function getCurrentDir(): string {
return __DIR__ ;
}
public function getReferer(): string {
return $_SERVER['HTTP_REFERER'] ?? 'Unbekannt';
}
public function getWebsite(): string {
return $_SERVER['HTTP_HOST'] ?? 'Unbekannt';
}
public function getDatabase(): string {
$conn = db_connect();
return $conn->host_info;
}
public function getLoggingStatus($variable) {
$status = DatabaseShow(
"Variablen",
"WERT",
"VARIABLENNAME = ?",
$variable
);
return $status;
}
public function getServerName(): string {
$Servername = $_SERVER['SERVER_NAME'] ?? 'Unbekannt';
if (in_array($Servername, ['Unbekannt', '0.0.0.0', '127.0.0.1'])) {
return "Lokal";
} else {
return $Servername;
}
}
public function getServerIP(): string {
$ServerIP = $_SERVER['SERVER_ADDR'] ?? 'Unbekannt';
if (in_array($ServerIP, ['Unbekannt', '0.0.0.0', '127.0.0.1'])) {
return "Lokal";
} else {
return $ServerIP;
}
}
public function getClientIP(): string {
$xff = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null;
if ($xff) {
$ips = array_map('trim', explode(',', $xff));
$clientIp = $ips[0];
return $clientIp;
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
public function getRequestTime(): string {
date_default_timezone_set('Europe/Berlin');
$timestamp = $_SERVER['REQUEST_TIME'] ?? time();
return date('Y-m-d H:i:s', $timestamp);
}
function getGeoIP($ClientIP) {
if (in_array($ClientIP, ['0.0.0.0', '127.0.0.1', '172.30.0.1'])) {
return "Lokal";
} elseif (in_array($ClientIP, ['Unbekannt', '0.0.0.0', '127.0.0.1'])) {
return "Lokal";
} else {
$response = file_get_contents("http://ip-api.com/json/{$ClientIP}?fields=country,countryCode");
$data = json_decode($response);
return $data->country;
}
}
function getWhitelistedIPs() {
include_once(__DIR__ . '/../utils/databaseMethods.php');
$data = DatabaseShow(
"Whitelisted",
"`IP-ADDRESSE`"
);
$results = [];
foreach ($data as $row) {
$results[] =$row['IP-ADDRESSE'];
}
return $results;
}
function getServerNode($ServerIP) {
$nodes = [
'node1' => '172.30.0.11',
'node1' => '172.30.0.21',
'node2' => '172.30.0.12',
'node2' => '172.30.0.22',
'node3' => '172.30.0.13',
'node3' => '172.30.0.23',
'node4' => '172.30.0.14',
'node4' => '172.30.0.24',
'Lokal' => 'Lokal',
];
foreach ($nodes as $node => $ip) {
if ($ServerIP == $ip) {
return $node;
break;
}
}
}
function getClientStatus($ClientIP) {
if (in_array($ClientIP, $this->getWhitelistedIPs())) {
return "Trusted";
}
return "Untrusted";
}
function getIsAdmin(){
return $_SESSION['is_admin'] ?? false;
}
function getIsSuperuser(){
return $_SESSION['is_superuser'] ?? false;
}
function getUsername(){
return $_SESSION['username'] ?? 'Gast';
}
public function getAllData(): array {
return [
'Server - Document Root' => $this->getDocumentRoot(),
'Server - Current Dir' => $this->getCurrentDir(),
'Server - Name' => $this->getServerName(),
'Server - IP' => $this->getServerIP(),
'Server - Port' => $this->getServerPort(),
'Server - Node' => $this->getServerNode($this->getServerIP()),
'Server - Database' => $this->getDatabase(),
'Request - URL' => $this->getRequestURL(),
'Request - Method' => $this->getRequestMethod(),
'Request - Query' => $this->getQuery(),
'Request - Referer' => $this->getReferer(),
'Request - Time' => $this->getRequestTime(),
'Client - IP' => $this->getClientIP(),
'Client - Port' => $this->getClientPort(),
'Client - Country' => $this->getGeoIP($this->getClientIP()),
'Client - User Agent' => $this->getUserAgent(),
'Client - Cookie USER' => $this->getCookie('USER'),
'Client - Cookie SESSSRV' => $this->getCookie('SESSSRV'),
'Client - Session ID' => $this->getSessionID(),
'Access - Whitelisted' => $this->getClientStatus($this->getClientIP()),
'Access - Whitelisted IPs' => $this->getWhitelistedIPs(),
'User - Username' => $this->getUsername(),
'User - Is Admin' => $this->getIsAdmin(),
'User - Is Superuser' => $this->getIsSuperuser(),
'System - Website' => $this->getWebsite(),
'Logging - Public' => $this->getLoggingStatus('GENERAL_PUBLIC_LOGGING')[0]['WERT'],
'Logging - Public DEV' => $this->getLoggingStatus('DEV_PUBLIC_LOGGING')[0]['WERT'],
'Logging - Backend' => $this->getLoggingStatus('GENERAL_BACKEND_LOGGING')[0]['WERT'],
'Logging - Backend DEV' => $this->getLoggingStatus('DEV_BACKEND_LOGGING')[0]['WERT'],
];
}
public function ShowAllData(): void {
$SpecificData = (new getSpecificData())->getAllData();
echo "<pre>";
foreach ($SpecificData as $key => $value) {
if (is_array($value)) {
$value = implode(', ', $value);
}
printf("%-22s : %s\n", $key, $value);
}
echo "</pre>";
}
}
+31
View File
@@ -0,0 +1,31 @@
APP_ENV = "vpn"
DB_LOCAL_HOST = "127.0.0.1"
DB_LOCAL_USERNAME = "worker"
DB_LOCAL_PASSWORD = "bBHofurUJWKzPE8Z"
DB_LOCAL_DATABASE = "DEV"
DB_VPN_HOST = "100.123.136.86"
DB_VPN_USERNAME = "worker"
DB_VPN_PASSWORD = "bBHofurUJWKzPE8Z"
DB_VPN_DATABASE = "DEV"
DB_BACKUP_HOST = "10.233.1.241"
DB_BACKUP_USERNAME = "worker"
DB_BACKUP_PASSWORD = "bBHofurUJWKzPE8Z"
DB_BACKUP_DATABASE = "DEV"
DB_DEV_HOST = "10.233.1.243"
DB_DEV_USERNAME = "worker"
DB_DEV_PASSWORD = "bBHofurUJWKzPE8Z"
DB_DEV_DATABASE = "DEV"
DB_LIVE_HOST = "10.233.1.244"
DB_LIVE_USERNAME = "worker"
DB_LIVE_PASSWORD = "bBHofurUJWKzPE8Z"
DB_LIVE_DATABASE = "DEV"
DB_ERROR_HOST = "10.233.1.244"
DB_ERROR_USERNAME = "error"
DB_ERROR_PASSWORD = "bBHofurUJWKzPE8Z"
DB_ERROR_DATABASE = "DEV"
+116
View File
@@ -0,0 +1,116 @@
<?php
require(__DIR__ . '/../utils/formatter.php');
class ApiController {
use ReponseFormatter;
/**
* method for pretty jsonsuccess output
*
* @param array $data
* @return string
*/
public function jsonSuccess($data) {
return $this->formatJson("success", $data);
}
/**
* method for pretty jsonerror output
*
* @param array $error
* @return string
*/
public function jsonError ($error) {
return $this->formatJson("failed", $error);
}
/**
* get authentication key out database
*
* @return array
*/
private function getAuthKey () {
$validTokens = DatabaseShow(
"API_Credentials",
"TOKEN"
);
return array_column($validTokens, 'TOKEN');
}
/**
* url authentication method via token and optional parameter function
*
* @param string $token
* @param string $function
* @return void
*/
public function urlAuth ($token, $function = '') {
$validTokens = $this->getAuthKey();
if (!in_array($token, $validTokens)) {
http_response_code(401);
$error = $this->formatJson("error", $token);
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function,
$error
);
errorMail(
"API Login failed",
$error,
true,
);
return false;
}
return true;
}
public function requestSave($function = '') {
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$_GET['token'],
(new getSpecificData())->getRequestURL(),
$function,
'{"status": "success"}',
);
}
/**
* create new api token
*
*/
private function createToken() {
return bin2hex(random_bytes(32));
}
/**
* save created api token
*
* @return bool
*/
public function saveToken() {
try {
DatabaseInsert(
"API_Credentials",
"TOKEN, BENUTZER",
$this->createToken(),
"API-User"
);
} catch (Exception $error) {
return false;
}
return true;
}
}
Loaded 100 of 129 files, more files were not shown because too many files have changed in this diff. Show more