]> git.leonardobizzoni.com Git - highschool-graduation-project/commitdiff
Docs and list page
authorLeonardoBizzoni <leo2002714@gmail.com>
Thu, 26 May 2022 13:48:45 +0000 (15:48 +0200)
committerLeonardoBizzoni <leo2002714@gmail.com>
Thu, 26 May 2022 13:48:45 +0000 (15:48 +0200)
README.org
dockerfiles/README.org
media/dbER.jpg [new file with mode: 0644]
www/Migrations/m_1653570702_notificationColFavVtuber.php [new file with mode: 0644]
www/README.org
www/controllers/SiteController.php
www/pub/css/list.css [new file with mode: 0644]
www/pub/css/main.css [deleted file]
www/views/layouts/list.php
www/views/layouts/main.php
www/views/list.php

index 7ad1dd621b72dd38748323289f3350d4ad294d31..5684fafa7dcd4d8531fd0559382afba7c3b0b145 100644 (file)
@@ -45,7 +45,6 @@ Il suo compito principale è quello di mostrare e ricevere informazioni dal clie
 
 Ho deciso di utilizzare Nginx come web server per le migliori performance e leggerezza in confronto ad altri web server.
 Inoltre la configura di Nginx è molto più semplice di web server come Apache.
-[[./media/nginxApacheGraph.png]]
 
 *** Application Layer - PHP
 L'application layer rappresenta il cuore dell'applicazione.
@@ -67,10 +66,11 @@ Il data layer si occupa della gestione ed immagazinamento dei dati generati dall
 
 L'installazione del database server mariadb viene anch'essa eseguita tramite un docker container e la container image disponibile su [[https://hub.docker.com/_/mariadb][hub.docker]] per cui non ha bisogno di alcuna configurazione.
 
-**** Schema E/R
+**** Schema E/R ed analisi delle molteplicità
 [[./media/dbER.jpg]]
 
-#TODO: descrizione schema ER
+Un utente può avere più vtuber preferite.
+Una vtuber può essere la preferita di più utenti.
 
 **** Schema logico
 [[./media/dbLogico.jpg]]
index 5ae4ac62216de4ca11afefe607f478b50c8f4f56..2cd74833986b4bb9ad0f5ca507d6676b69bfa3c3 100644 (file)
@@ -1,9 +1,18 @@
 #+TITLE: Containers
 
 * Contenuti :TOC:
+- [[#perchè-i-container][Perchè i container]]
 - [[#gestione-containers][Gestione containers]]
 - [[#creazione-ed-esecuzione-containers][Creazione ed esecuzione containers]]
 
+* Perchè i container
+Ho deciso di realizzare questo progetto utilizzando i container per poter separare i processi server in esecuzione dall'ambiente di sviluppo.
+In questo modo ho a disposizione 3 container isolati, con il proprio file system, che sono facilmente spostabili ad altre macchine.
+
+Un'alternativa ai container poteva essere l'utilizzo delle virtual machine che però possono causare svariati problemi:
+- utilizzo maggiore delle risorse hardware, dato che una virtual machine ha il proprio hardware virtuale, il proprio sistema operativo, i propri driver e servizi in esecuzione
+- maggiore difficoltà nell'installazione e configurazione dei server, tramite Dockerfile e docker-compose configurare ed installare i server nel container è molto semplice a differenza delle VM dove è necessario eseguire tutto manualmente
+
 * Gestione containers
 La creazione e gestione dei container viene effettuata tramite *docker-compose* ed il file di configurazione [[./docker-compose.yml][docker-compose.yml]].
 Il file di configurazione utilizza il linguaggio markup YAML ed è composto da 2 parti principali:
diff --git a/media/dbER.jpg b/media/dbER.jpg
new file mode 100644 (file)
index 0000000..a4fb8c9
Binary files /dev/null and b/media/dbER.jpg differ
diff --git a/www/Migrations/m_1653570702_notificationColFavVtuber.php b/www/Migrations/m_1653570702_notificationColFavVtuber.php
new file mode 100644 (file)
index 0000000..c638cb0
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+use app\core\Application;
+
+class m_1653570702_notificationColFavVtuber
+{
+    public function up()
+    {
+        $db = Application::$app->db;
+        $sql = "ALTER TABLE favoriteVtuber ADD COLUMN notify BOOL DEFAULT 1;";
+        $db->pdo->exec($sql);
+    }
+
+    public function down()
+    {
+        $db = Application::$app->db;
+        $sql = "ALTER TABLE favoriteVtuber DROP COLUMN notify;";
+        $db->pdo->exec($sql);
+    }
+}
+?>
index 47ca1226c07f0c025d535705a93a41a3e580bfd0..d049e9d5718a226b8a083c7561e22bf83462de26 100644 (file)
 
 * Realizzazione
 La web app è strutturata seguendo il *Model View Controller* framework.
+Quando un utente visita la pagina, viene inizializzato il core dell'applicazione.
+Il core è dotato di diversi classi fondamentali per il corretto funzionamento della web app, tra cui:
+- Application
+- Router
+- Session
+- Le base class per model e controller
+
 Per gestire le dipendenze e namespaces di PHP viene utilizzato *composer*.
 
 ** Entry point - index.php
-La home page, si occupa di inizializzare l'applicazione ed impostare le route con annesso array [Controller, metodo].
+La home page, si occupa di inizializzare l'applicazione ed impostare le route.
+Una route è formata da:
+- *metodo*: rappresentato dal metodo della classe router utilizzato (/come in esempio/)
+- *path*: il primo parametro da passare al metodo get/post del router (nell'esempio "/")
+- *callback*: il secondo parametro da passare al metodo e può essere:
+    + una funzione che verrà eseguita quando l'utente visita il path specificato
+    + il nome di una *view*, deve coincidere con un file nella directory view
+    + un array formato da [ *ControllerClass*, "*metodo*" ]
 
 #+begin_src php
 $app = new Application(dirname(__DIR__));
-$app->router->get("/", [SiteController::class, "home"]);
-#+end_src
 
-** Core
-*** Main application class
-La classe principale, si occupa di istanziare:
-- la Router class
-- la Request helper class
-- la Response helper class
+# Esempio con funzione
+$app->router->get("/esempio0", function () {
+    echo "hello world!";
+});
 
-Rappresenta il fulcro della web app.
-Rende possibile l'accesso a tutte le classi da essa istaziate tramite la viariabile statica "$app".
+# Esempio con sola view
+$app->router->get("/esempio1", "home");
+
+# Esempio con controller
+$app->router->get("/esempio2", [SiteController::class, "home"]);
+#+end_src
 
-Gestisce tutti i controller tramite "BaseController".
+Una volta impostate tutte le route disponibili viene chiamato il metodo "run()".
+Questo metodo a sua volta chiama il router per risolvere la richiesta effettuata utente.
 
+** Core
 *** Router class
 Una delle classi principali è il Router, gestisce l'array associativo "$routes" e la risoluzione delle varie request effettuate.
 
@@ -136,8 +152,8 @@ if ($ruleName == self::RULE_MATCH && $value != $this->{$rule["match"]}) {
 #+end_src
 
 *** Database class
-Il compito della Database class è quello di effettuare una connessione al server mariadb in esecuzione sul docker container ed applicare delle [[./www/Migrations][migration]].
-Sia le credenziali di accesso al database che il domain service name (DSN) sono salvate nel file "www/.env" (vedi [[./www/.env.example][.env.example]]) e per leggerle si utilizza il package [[https://github.com/vlucas/phpdotenv][phpdotenv]].
+Il compito della Database class è quello di effettuare una connessione al server mariadb in esecuzione sul docker container ed applicare delle [[./Migrations][migration]].
+Sia le credenziali di accesso al database che il domain service name (DSN) sono salvate nel file "www/.env" (vedi [[./.env.example][.env.example]]) e per leggerle si utilizza il package [[https://github.com/vlucas/phpdotenv][phpdotenv]].
 
 Installazione phpdotenv:
 #+begin_src bash
@@ -150,13 +166,9 @@ Attraverso il metodo "applyMigrations()" la Database class è in grado di:
 - selezionare le migration presenti nella migration table
 - per ogni migration non presente nel DB, creare un'istanza ed esegue il metodo "up()"
 
-*** Database model class
-La classe DbModel si basa sulla base Database class ma viene trattata come l'effettiva SQL table.
-
 ** Migrations
-
 È importante che le migration class siano ordinate e che seguano tutte lo stesso stile di nomeclatura.
-La creazione di una migration class può essere effettuata tramite lo script [[./scripts/createMigration.sh][createMigration]].
+La creazione di una migration class può essere effettuata tramite lo script [[../scripts/createMigration.sh][createMigration]].
 #+begin_src bash
 ./scripts/createMigration pathToMigrationsDir migrationName
 #+end_src
@@ -168,7 +180,7 @@ Ogni migration class è formata da _almeno_ 2 metodi:
 - "down()": esegue del codice SQL per annullare la modifica
 
 ** Models
-Le classi "Model" gestiscono i dati presenti nel database e controlla che i dati seguano delle determinate regole.
+Le classi "Model" gestiscono i dati presenti nel database o inseriti dall'utente e controllano che i dati seguano delle determinate regole.
 Tutte le classi Model derivano dalla classe "BaseModel" o "DbModel".
 
 *** Registration model - User model
@@ -192,13 +204,22 @@ Model utilizzato per interagire con il database di vtuber.
 
 Simile al model di registrazione ma con 2 importanti metodi:
 - *getVtuberInfo()*: controlla che il link inserito sia l'URL ad un canale twitch o youtube ed utilizzando i rispettivi API(Twitch o Google) recupara le informazioni della vtuber in questione
-- *isLive()*: controlla se la vtuber in questione è live o no, utilizzando l'API Twitch o tramite curl request per canali YT
+- *isLive()*: controlla se la vtuber in questione è live o no
 
 ** Controllers
-Le classi "Controller" svolgono il ruolo di ponte.
+Le classi "Controller" svolgono il ruolo di ponte tra:
+- view <-> utente
+- view <-> model
+
 Esse permettono ai dati di apparire nella View richiesta dall'utente una volta prelevati dal database o di venirvi inseriti tramite una form.
 
 *** Authentication controller
-L'authentication controller ha 2 compiti fondamentali:
-- registrare nuovi utenti con l'aiuto della classe "RegisterModel"
-- permettere l'accesso ad utenti già registrati
+L'authentication controller ha 3 compiti fondamentali:
+- registrare nuovi utenti (register)
+- permettere l'accesso ad utenti già registrati (login)
+- permettere ad utente registrati di uscire dal proprio account (logout)
+
+*** SiteController
+Questo controller è il controller principale della pagina, implementa infatti i 2 metodi:
+- *list()*: effettua il check dei dati in trasito verso la pagina contente la lista di vtuber preferite dell'utente
+- *live()*: effettua il check dei dati in trasito verso la pagina principale
index d08b973718ad6cfd9bb71a2c90100963c8a81c6d..8f2992a27b3f6923a1800bedc91a201e17466d2b 100644 (file)
@@ -9,10 +9,24 @@ use app\models\Vtubers;
 
 class SiteController extends BaseController
 {
-    public function list()
+    public function list(Request $req)
     {
         Application::$app->router->title = "WeebSite - Your top vtubers";
         $this->setLayout("list");
+
+        if ($req->getMethod() == "post") {
+            if (isset($req->getBody()["rem"])) {
+                $stmt = Application::$app->db->pdo->prepare("DELETE FROM favoriteVtuber WHERE _userID=" . Application::$app->user->id . " AND _vtuberID=" . $req->getBody()["rem"]);
+                $stmt->execute();
+            } else if (isset($req->getBody()["notNotify"])) {
+                $stmt = Application::$app->db->pdo->prepare("UPDATE favoriteVtuber SET notify=0 WHERE _vtuberID=" . $req->getBody()["notNotify"]);
+                $stmt->execute();
+            } else if (isset($req->getBody()["notify"])) {
+                $stmt = Application::$app->db->pdo->prepare("UPDATE favoriteVtuber SET notify=1 WHERE _vtuberID=" . $req->getBody()["notify"]);
+                $stmt->execute();
+            }
+        }
+
         return $this->render("list");
     }
 
@@ -41,9 +55,9 @@ class SiteController extends BaseController
             $statement->execute();
 
             foreach ($statement->fetchAll() as $vtuber) {
-                $params[] = [ $vtuber, $vtuberModel->isLive($vtuber["login"], $vtuber["link"]) ];
+                $params[] = [$vtuber, $vtuberModel->isLive($vtuber["login"], $vtuber["link"])];
                 if ($singleVtuber) {
-                    Application::$app->router->title = "WeebSite - ".$vtuber["username"];
+                    Application::$app->router->title = "WeebSite - " . $vtuber["username"];
                 }
             }
         }
diff --git a/www/pub/css/list.css b/www/pub/css/list.css
new file mode 100644 (file)
index 0000000..e2862cb
--- /dev/null
@@ -0,0 +1,8 @@
+.vtuber-img {
+    width: 88px;
+    height: 88px;
+}
+
+td {
+    vertical-align: middle;
+}
diff --git a/www/pub/css/main.css b/www/pub/css/main.css
deleted file mode 100644 (file)
index e69de29..0000000
index 26b9e6b8925bfc3aedc524888ae81a5edd7f5eca..c989aca35d5182e3f5cdbab18664ca6d2ffec5f0 100644 (file)
@@ -9,9 +9,9 @@ use app\core\Application;
 <head>
     <meta charset="UTF-8" />
     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
-    <link rel="stylesheet" href="/css/main.css" type="text/css" media="screen" />
+    <link rel="stylesheet" href="/css/list.css" type="text/css" media="screen" />
 
-    <title>Document</title>
+    <title><?= $this->title ?></title>
 </head>
 
 <body>
@@ -48,6 +48,7 @@ use app\core\Application;
                     <th scope="col">Username</th>
                     <th scope="col"></th>
                     <th scope="col"></th>
+                    <th scope="col"></th>
                 </tr>
             </thead>
             <tbody class="table-group-divider">
index a4a71f849614209be5d046cff1f16d2081f3002a..e5e2f63ffd267d26c0891058cafbcac887678571 100644 (file)
@@ -9,7 +9,6 @@ use app\core\Application;
 <head>
     <meta charset="UTF-8" />
     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
-    <link rel="stylesheet" href="/css/main.css" type="text/css" media="screen" />
 
     <title><?= $this->title ?></title>
 </head>
index 30b09cebf8577a0bab2a977b380082a98854c700..b9050f200230dc4ad7d66b293195105746ce78a6 100644 (file)
@@ -2,12 +2,49 @@
 
 use app\core\Application;
 
-if (!Application::isGuest()) :
-?>
+if (!Application::isGuest()) {
+    $stmt = Application::$app->db->pdo->prepare("
+SELECT vtubers.id, img, vtubers.username, notify
+FROM users, vtubers, favoriteVtuber
+WHERE users.id = _userID
+AND vtubers.id = _vtuberID
+AND users.id = ". Application::$app->user->id);
+    $stmt->execute();
 
+    while ($row = $stmt->fetch()) {
+        if ($row["notify"] == 1) {
+            $disable = "";
+            $enable = "disabled";
+        } else {
+            $disable = "disabled";
+            $enable = "";
+        }
 
-<?php
-else:
-    Application::$app->res->redirect("/");
+        echo "
+<tr>
+<td><img class='vtuber-img' src=\"{$row["img"]}\"/></td>
+<td>{$row["username"]}</td>
+<td>
+    <form method='POST'>
+        <button type='submit' name='rem' value='{$row["id"]}' class='btn btn-outline-danger'>Remove from favorites</button>
+    </form>
+</td>
+<td>
+    <form method='POST'>
+        <button type='submit' name='notNotify' value='{$row["id"]}' class='btn btn-outline-danger' ". $disable .">Disable notifications</button>
+    </form>
+</td>
+<td>
+    <form method='POST'>
+        <button type='submit' name='notify' value='{$row["id"]}' class='btn btn-outline-primary' $enable>Enable notifications</button>
+    </form>
+</td>
+</tr>
+";
+    }
 
-endif; ?>
+}
+else {
+    Application::$app->res->redirect("/");
+}
+?>