From b455fdb20ebe9f47c542a9379a574ea02e89961b Mon Sep 17 00:00:00 2001 From: Kilian Hofmann Date: Mon, 29 Jul 2024 23:09:37 +0200 Subject: [PATCH] Readme --- exam/README.md | 82 ++++++++++++++++++++++++++++++- exam/classes/Models/User/User.php | 37 ++++++++------ 2 files changed, 104 insertions(+), 15 deletions(-) diff --git a/exam/README.md b/exam/README.md index 236f88c..a81d3a0 100644 --- a/exam/README.md +++ b/exam/README.md @@ -1,3 +1,83 @@ +# Übersicht der Inhalt + +### Fett markierte Verzeichnisse und deren Inhalt sind von besonderem Interesse + +- **api** + - docs + - API Dokumentation (openAPI 3.0) + - Login + - `/api/login` Endpunkt Klasse `Login.php` + - Logout + - `/api/login` Endpunkt Klasse `Logout.php` + - Posts + - `/api/posts` Endpunkt Klasse `Posts.php` + - `/api/posts/{id}` Endpunkt Klasse `Posts.php` + - Refresh + - `/api/refresh` Endpunkt Klasse `Refresh.php` + - Register + - `/api/register` Endpunkt Klasse `Register.php` + - Users + - `/users` Endpunkt Klasse `Users.php` + - `/users/{id}` Endpunkt Klasse `Users.php` + - Image + - `/users{id}/image` Endpunkt Klasse `Image.php` + - Posts + - `/users{id}/posts` Endpunkt Klasse `Posts.php` + - `index.php` + - API Einstiegspunkt +- **classes** + - Api + - `Api.php`: Basisklasse für Endpunkte + - ApiError + - `ApiError.php`: Facade für Fehler die das Api zurück gibt + - Auth + - `AdminAuth.php`: Middleware für Authentifizierung zuzüglich Admin Rechte + - `Auth.php`: Middleware für Authentifizierung + - `OptAuth.php`: Middleware für optionale Authentifizierung + - Config + - `Config.php`: Singleton für Applikationskonfiguration + - Database + - `Database.php`: Singleton für Datenbankzugriffe (Wrapper um PDO) + - GUID + - `GUID.php`: Facade für GUID Algorithmen + - Input + - `Input.php`: Facade die SimpleRouters `Input` Klasse wrapped für + einfacheren Zugriff auf häufig verwendete Methoden + - Models + - Post + - `Post.php`: Modellklasse für Posts. Abstrahiert und kapselt + Datenbankzugriffe + - User + - `User.php`: Modellklasse für User. Abstrahiert und kapselt + Datenbankzugriffe + - Request + - `Request.php`: Facade die SimpleRouters `Request` Klasse wrapped für + einfacheren Zugriff auf häufig verwendete Methoden + - Response + - `Response.php`: Facade die SimpleRouters `Response` Klasse wrapped für + einfacheren Zugriff auf häufig verwendete Methoden +- **config** + - `app.php`: Applikationskonfiguration + - `database.php`: Datenbankverbindungsdaten +- dist + - React Buildartefakte. +- react + - React Projekt +- **routes** + - `routes.php`: SimpleRouter Routenkonfiguration für die Applikation +- storage: + - Speicherort für Profilbilder +- **utils**: + - `helpers.php`: Kleine Helferlein +- vendor: + - Verzeichnis für Composer Pakete + +# Autoloader + +Verwendet wird hier der Composer Autoloader. Konfiguriert werden dessen +Namespaces in der `composer.json`. Durch `composer dump-autoload` wird +der Autoloader aktualisiert sollten neue Namespaces hinzugefügt werden. + # Voraussetzungen um das React Projekt zu bauen - Node 18 - PNPM @@ -18,7 +98,7 @@ ## Tabelle `egb_gaestebuch` - Abänderung der Spalte `benutzer_id`: Non-Nullable gemacht - Abänderung der Spalte `beitrag`: Non-Nullable gemacht -- Hinzufüge eines Foreign Key Constraints auf `benutzer_id` +- Hinzufüge eines Foreign Key Constraints auf `benutzer_id` mit CASCADE (Löschen des Users löscht Beiträge) # Notwendige Anpassung für die Verzeichnisstruktur eines anderen Hosters diff --git a/exam/classes/Models/User/User.php b/exam/classes/Models/User/User.php index 53f126c..f188782 100644 --- a/exam/classes/Models/User/User.php +++ b/exam/classes/Models/User/User.php @@ -528,26 +528,21 @@ class User implements JsonSerializable { $db = Database::getInstance(); + // Grab old picture + $stmt = $db->prepare("SELECT image FROM egb_benutzer WHERE id = :ID"); + $stmt->bindValue(":ID", $this->id); + $stmt->execute(); + $oldImage = $stmt->fetch(PDO::FETCH_COLUMN, 0); + // Make sure we do all changes or none $db->beginTransaction(); $failed = []; $reasons = []; - - try { - $stmt = $db->prepare("SELECT image FROM egb_benutzer WHERE id = :ID"); - $stmt->bindValue(":ID", $this->id); - $stmt->execute(); - $oldImage = $stmt->fetch(PDO::FETCH_COLUMN, 0); - if (strpos($oldImage, "default") === false) unlink(Config::getStorageFSPath() . $oldImage); - } catch (Exception $e) { - } - if (!empty($image)) { - // Move file and grab filename + // Generate new filename $destinationFilename = sprintf('%s.%s', uniqid(), $image->getExtension()); - $image->move(Config::getStorageFSPath() . "profilbilder/$destinationFilename"); - + // Try and update user record try { $stmt = $db->prepare("UPDATE egb_benutzer SET image = :IMG WHERE id = :ID"); $stmt->bindValue(":IMG", "profilbilder/$destinationFilename"); @@ -557,6 +552,8 @@ class User implements JsonSerializable array_push($failed, "image"); array_push($reasons, "generic"); } + // Move file + $image->move(Config::getStorageFSPath() . "profilbilder/$destinationFilename"); } catch (Exception $e) { array_push($failed, "image"); if ($e->getCode() === "23000") { @@ -594,11 +591,17 @@ class User implements JsonSerializable // Commit the changes $db->commit(); + // Delete old picture if it isn't a default one and if it exists. + try { + if (strpos($oldImage, "default") === false) unlink(Config::getStorageFSPath() . $oldImage); + } catch (Exception $e) { + } + return User::getByID($this->id); } /** - * Delete user + * Delete user and image * * @param int $limit Limit of list for which the returned pages is calculated. * @@ -619,6 +622,12 @@ class User implements JsonSerializable $stmt->execute(); $count = $stmt->fetch(PDO::FETCH_COLUMN, 0); + // Delete picture if it isn't a default one and if it exists. + try { + if (strpos($this->image, "default") === false) unlink(Config::getStorageFSPath() . $this->image); + } catch (Exception $e) { + } + return ["pages" => intdiv($count, $limit + 1) + 1, "data" => $this]; }