]> git.leonardobizzoni.com Git - highschool-graduation-project/commitdiff
Login to existing account
authorLeonardoBizzoni <leo2002714@gmail.com>
Wed, 4 May 2022 09:20:58 +0000 (11:20 +0200)
committerLeonardoBizzoni <leo2002714@gmail.com>
Wed, 4 May 2022 09:20:58 +0000 (11:20 +0200)
16 files changed:
README.org
www/controllers/AuthController.php
www/controllers/SiteController.php
www/core/Application.php
www/core/BaseModel.php
www/core/DbModel.php
www/core/Response.php
www/core/Session.php [new file with mode: 0644]
www/core/forms/Field.php
www/models/LoginForm.php [new file with mode: 0644]
www/models/User.php
www/models/Vtubers.php
www/pub/index.php
www/views/layouts/main.php
www/views/live.php
www/views/login.php

index f662ed891fae80b5ec51b7aeb19c727d5e014b2e..18a2ba27126cbf6fbf7a48a1fa642f48a7bff882 100644 (file)
@@ -243,15 +243,30 @@ Ogni migration class è formata da _almeno_ 2 metodi:
 
 ** Models
 Le classi "Model" gestiscono i dati presenti nel database e controlla che i dati seguano delle determinate regole.
-Tutte le classi Model derivano dalla classe "BaseModel".
+Tutte le classi Model derivano dalla classe "BaseModel" o "DbModel".
 
-*** Registration model
+*** Registration model - User model
 Il model di registrazione si occupa della gestione dei dati di nuovi utenti e dell'interazione con il database.
 
 Attraverso l'implementazione del metodo astratto "rules()" si possono impostare le regole che i campi della form dovranno seguire.
-*Attenzione*: i nomi dei parametri, i nomi inseriti nella array resistituito da "rules()" ed i nomi dei [[./www/core/forms/Field.php][Field]] _devono_ essere uguali.
 
-# TODO: register()
+I nomi dei parametri di questa classe non devono necessariamente coincidere con i label visibili dall'utente.
+Questo perchè utilizzando il metodo "labels()" è possibile mappare i nomi dei parametri ai label che appaiono all'utente.
+
+L'effettiva registrazione dell'utente attraverso l'inserimento dei valori all'interno del database viene eseguita dal metodo "save()".
+"save()" è un metodo a cui tutti i model che estendono "DbModel" possono accedere, questo perchè sono la rappresentazione della tabella presente nel database.
+
+*** Login model - LoginForm model
+Model molto semplice, non basato sul DbModel ma bensì sul BaseModel in quanto non deve interagire direttamente con il database.
+
+Inviata la POST request per effettuare il login esso cerca nel database un utente che abbia l'indirizzo email fornito dall'utente, se lo trova controlla la correttezza della password.
+
+*** Vtuber model
+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
 
 ** Controllers
 Le classi "Controller" svolgono il ruolo di ponte.
@@ -261,4 +276,3 @@ Esse permettono ai dati di apparire nella View richiesta dall'utente una volta p
 L'authentication controller ha 2 compiti fondamentali:
 - registrare nuovi utenti con l'aiuto della classe "RegisterModel"
 - permettere l'accesso ad utenti già registrati
-# TODO
index 4671a2986ff60dfe17e825ddd0f0ad8bc0094507..6456621fd5138ec1f33583c26a94bcb8b1caa4b2 100644 (file)
@@ -1,26 +1,36 @@
 <?php
 namespace app\controllers;
 
+use app\core\Application;
 use app\core\BaseController;
 use app\core\Request;
+use app\models\LoginForm;
 use app\models\User;
 
 class AuthController extends BaseController{
-    public function login() {
-        // $this->setLayout("auth");
-        return $this->render("login");
+    public function login(Request $req) {
+        $loginForm = new LoginForm;
+
+        if ($req->getMethod() == "post"){
+            $loginForm->loadData($req->getBody());
+
+            if ($loginForm->validate() && $loginForm->login()) {
+                Application::$app->res->redirect("/");
+                return;
+            }
+        } 
+
+        return $this->render("login", [ "model" => $loginForm ]);
     }
 
     public function register(Request $req) {
-        // $this->setLayout("auth");
-        $errors = [];
         $registerModel = new User;
 
         if ($req->getMethod() == "post") {
             $registerModel->loadData($req->getBody());
 
             if ($registerModel->validate() && $registerModel->register()) {
-                return "Success";
+                Application::$app->res->redirect("/");
             }
         }
         return $this->render("register", [ "model" => $registerModel ]);
index dbb3d962ab97f101f44344e698ca52f9b0459bd0..cbf3fe1f8875a954d8ba6d169bc0341684940ea8 100644 (file)
@@ -21,29 +21,28 @@ class SiteController extends BaseController
     public function live(Request $req)
     {
         $params = [];
+        $statement = Application::$app->db->pdo->prepare("SELECT * FROM vtubers;");
         $vtuberModel = new Vtubers;
 
         if ($req->getMethod() == "post") {
             $vtuberModel->loadData($req->getBody());
-            $vtuberModel->getVtuberName();
+            $vtuberModel->getVtuberInfo();
 
             if ($vtuberModel->validate() && $vtuberModel->register()) {
-                return "Success";
+                Application::$app->res->redirect("/");
             }
         } else if ($req->getMethod() == "get") {
-            $statement = Application::$app->db->pdo->prepare("SELECT * FROM vtubers;");
+            if (isset($_GET["id"])) {
+                $this->setLayout("live");
+                $statement = Application::$app->db->pdo->prepare("SELECT * from vtubers where id={$_GET['id']}");
+            }
             $statement->execute();
 
             foreach ($statement->fetchAll() as $vtuber) {
-                $params[] = ["vtuber" => [ $vtuber, $vtuberModel->isLive($vtuber["login"], $vtuber["link"]) ]];
+                $params[] = [ $vtuber, $vtuberModel->isLive($vtuber["login"], $vtuber["link"]) ];
             }
-                // echo "<pre>";
-                // var_dump($params);
-                // echo "</pre";
         }
 
-        if (isset($_GET["id"]))
-            $this->setLayout("live");
         return $this->render("live", ["model" => $vtuberModel, $params]);
     }
 }
index dec27fbb05c0cc9df2b430046e797171c3a08ad8..7922f6df575f243e76a5f3cb2aec5803d1e01c1e 100644 (file)
@@ -4,11 +4,14 @@ namespace app\core;
 class Application {
     private BaseController $controller;
 
+    public $userClass;
+    public array $config;
     public Router $router;
     public Request $req;
     public Response $res;
     public Database $db;
-    public array $config;
+    public Session $session;
+    public ?DbModel $user = null;
 
     public static Application $app;
     public static string $ROOT_DIR;
@@ -17,11 +20,20 @@ class Application {
         self::$ROOT_DIR = $root;
         self::$app = $this;
 
+        $this->userClass = $config["userClass"];
         $this->config = $config;
         $this->req = new Request();
         $this->res = new Response();
         $this->router = new Router($this->req, $this->res);
+        $this->session = new Session;
+
         $this->db = new Database($config["db"]);
+
+        $primaryValue = $this->session->get("user");
+        if ($primaryValue) {
+            $primaryKey = $this->userClass::primaryKey();
+            $this->user = $this->userClass::findOne([$primaryKey => $primaryValue]);
+        }
     }
 
     public function run() {
@@ -35,5 +47,20 @@ class Application {
     public function setController(BaseController $controller) {
         $this->controller = $controller;
     }
+
+    public function login(DbModel $user) {
+        $this->user = $user;
+        $primaryKey = $user->primaryKey();
+        $primaryValue = $user->{$primaryKey};
+
+        $this->session->set("user", $primaryValue);
+
+        return true;
+    }
+
+    public function logout() {
+        $this->user = null;
+        $this->session->remove("user");
+    }
 }
 ?>
index 9960ffee9a0c372341057d96f36f56215108e0eb..158be02a49b973d8e0ac51d6ada7ee09fd05e000 100644 (file)
@@ -21,6 +21,14 @@ abstract class BaseModel {
 
     abstract public function rules(): array;
 
+    public function labels(): array {
+        return [];
+    }
+
+    public function getLabel(string $attribute) {
+        return $this->labels()[$attribute] ?? $attribute;
+    }
+
     public function validate() {
         foreach ($this->rules() as $attribute => $rules) {
             $value = $this->{$attribute};
@@ -33,19 +41,19 @@ abstract class BaseModel {
                 }
 
                 if ($ruleName == self::RULE_REQUIRED && !$value) {
-                    $this->addError($attribute, self::RULE_REQUIRED);
+                    $this->internalAddError($attribute, self::RULE_REQUIRED);
                 }
                 if ($ruleName == self::RULE_EMAIL && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
-                    $this->addError($attribute, self::RULE_EMAIL);
+                    $this->internalAddError($attribute, self::RULE_EMAIL);
                 }
                 if ($ruleName == self::RULE_MIN && strlen($value) < $rule["min"]) {
-                    $this->addError($attribute, self::RULE_MIN, $rule);
+                    $this->internalAddError($attribute, self::RULE_MIN, $rule);
                 }
                 if ($ruleName == self::RULE_MAX && strlen($value) > $rule["max"]) {
-                    $this->addError($attribute, self::RULE_MAX, $rule);
+                    $this->internalAddError($attribute, self::RULE_MAX, $rule);
                 }
                 if ($ruleName == self::RULE_MATCH && $value != $this->{$rule["match"]}) {
-                    $this->addError($attribute, self::RULE_MATCH, $rule);
+                    $this->internalAddError($attribute, self::RULE_MATCH, $rule);
                 }
                 if ($ruleName == self::RULE_UNIQUE) {
                     $className = $rule["class"];
@@ -57,7 +65,7 @@ abstract class BaseModel {
                     $statement->execute();
 
                     if($statement->fetchObject()) {
-                        $this->addError($attribute, self::RULE_UNIQUE, ["field" => $attribute]);
+                        $this->internalAddError($attribute, self::RULE_UNIQUE, ["field" => $this->getLabel($attribute)]);
                     }
                 }
             }
@@ -66,14 +74,18 @@ abstract class BaseModel {
         return empty($this->errors);
     }
 
-    public function addError(string $attribute, string $rule, $params = []) {
+    private function internalAddError(string $attribute, string $rule, $params = []) {
         $message = $this->errorMessages()[$rule] ?? "";
         foreach ($params as $key => $value) {
-            $message = str_replace("{{$key}}", $value, $message);
+            $message = str_replace("{{$key}}", strtolower($this->getLabel($value)), $message);
         }
         $this->errors[$attribute][] = $message;
     }
 
+    public function addError(string $attribute, string $message) {
+        $this->errors[$attribute][] = $message;
+    }
+
     public function errorMessages() {
         return [
             self::RULE_REQUIRED => "This field is required",
index 11d286920ad34a02199a6a6e1cb26da0673aa0ab..5d90c040f9c7a6bc26de460c5339d8cf68f08e9f 100644 (file)
@@ -4,7 +4,8 @@ namespace app\core;
 
 abstract class DbModel extends BaseModel
 {
-    abstract public function tableName(): string;
+    abstract public static function tableName(): string;
+    abstract public static function primaryKey(): string;
     abstract public function attributes(): array;
 
     public function save()
@@ -23,6 +24,21 @@ abstract class DbModel extends BaseModel
         return true;
     }
 
+    public static function findOne(array $where) {
+        $tableName = static::tableName();
+        $attributes = array_keys($where);
+
+        $sql = implode(" AND ", array_map(fn($attr) => "$attr = :$attr", $attributes));
+
+        $statement = self::prepare("SELECT * FROM $tableName WHERE $sql");
+        foreach ($where as $key => $value) {
+            $statement->bindValue(":$key", $value);
+        }
+        $statement->execute();
+
+        return $statement->fetchObject(static::class);
+    }
+
     public static function prepare(string $sql) {
         return  Application::$app->db->pdo->prepare($sql);
     }
index 06c22955000e3773133a3df90d66e901ae63c47f..e5dcf3e9d098b7a08ffcc53149fd346531174659 100644 (file)
@@ -5,5 +5,9 @@ class Response {
     public function setStatusCode(int $code) {
         http_response_code($code);
     }
+
+    public function redirect(string $url) {
+        header("Location: $url");
+    }
 }
 ?>
diff --git a/www/core/Session.php b/www/core/Session.php
new file mode 100644 (file)
index 0000000..f8d9884
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+namespace app\core;
+
+class Session {
+
+    public function __construct()
+    {
+        session_start();
+    }
+
+    public function get($key) {
+        return $_SESSION[$key] ?? false;
+    }
+
+    public function set($key, $value) {
+        $_SESSION[$key] = $value;
+    }
+
+    public function remove($key) {
+        unset($_SESSION[$key]);
+    }
+}
+?>
index af33968ecf21d6087046e61ba7684988f6005549..997597b47c367bdefd73ddbc7fbb5b5bca0ed30a 100644 (file)
@@ -26,7 +26,7 @@ class Field {
     <input name="%s" type="%s" value="%s" class="form-control%s"/>
     <div class="invalid-feedback">%s</div>
 </div>',
-            ucfirst($this->attribute),
+            $this->model->getLabel($this->attribute),
             $this->attribute,
             $this->type,
             $this->model->{$this->attribute},
diff --git a/www/models/LoginForm.php b/www/models/LoginForm.php
new file mode 100644 (file)
index 0000000..45cc7f3
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+namespace app\models;
+
+use app\core\Application;
+use app\core\BaseModel;
+
+class LoginForm extends BaseModel
+{
+    public string $email = "";
+    public string $password = "";
+
+    public function rules(): array
+    {
+        return [
+            "email" => [self::RULE_REQUIRED, self::RULE_EMAIL],
+            "password" => [self::RULE_REQUIRED]
+        ];
+    }
+
+    public function login() {
+        $user = User::findOne(["email" => $this->email]);
+
+        if (!$user) {
+            $this->addError("email", "User does not exist!");
+            return false;
+        } else {
+            if (!password_verify($this->password, $user->password)) {
+                $this->addError("password", "Password is incorrect");
+                return false;
+            }
+        }
+
+        return Application::$app->login($user);
+    }
+
+    public function labels(): array
+    {
+        return [
+            "email" => "Your account email",
+            "password" => "The super secret password to your epic account"
+        ];
+    }
+}
index 4f3bb34b38704974443e98e418711ff034966282..7d291d3dcda36736dd14a39d72645ab0f4e13c7b 100644 (file)
@@ -13,11 +13,16 @@ class User extends DbModel
     public string $password = "";
     public string $confirm = "";
 
-    public function tableName(): string
+    public static function tableName(): string
     {
         return "users";
     }
 
+    public static function primaryKey(): string
+    {
+        return "id";
+    }
+
     public function attributes(): array {
         return [ "firstname", "lastname", "email", "username", "password" ];
     }
@@ -35,8 +40,20 @@ class User extends DbModel
             "lastname" => [self::RULE_REQUIRED],
             "username" => [self::RULE_REQUIRED],
             "email" => [self::RULE_REQUIRED, self::RULE_EMAIL, [self::RULE_UNIQUE, "class" => self::class ]],
-            "password" => [self::RULE_REQUIRED, [self::RULE_MIN, "min" => 20], [self::RULE_MAX, "max" => 100]],
+            "password" => [self::RULE_REQUIRED, [self::RULE_MIN, "min" => 1], [self::RULE_MAX, "max" => 100]],
             "confirm" => [self::RULE_REQUIRED, [self::RULE_MATCH, "match" => "password"]]
         ];
     }
+
+    public function labels(): array
+    {
+        return [
+            "firstname" => "First name",
+            "lastname" => "Last name",
+            "username" => "Your username",
+            "email" => "Email",
+            "password" => "Your super secret password",
+            "confirm" => "Confirm your super secret password",
+        ];
+    }
 }
index 3ac8372c823cdaa31c3ef85858a79f1f6dc9ed40..0f338083e51834e0f7cb3213f410324adf57039c 100644 (file)
@@ -15,16 +15,28 @@ class Vtubers extends DbModel
     public string $img = "";
     public string $link = "";
 
-    public function tableName(): string
+    public static function tableName(): string
     {
         return "vtubers";
     }
 
+    public static function primaryKey(): string
+    {
+        return "id";
+    }
+
     public function attributes(): array
     {
         return ["username", "login", "img", "link"];
     }
 
+    public function labels(): array
+    {
+        return [
+            "link" => "Vtuber channel link",
+        ];
+    }
+
     public function register()
     {
         return $this->save();
@@ -40,7 +52,7 @@ class Vtubers extends DbModel
         ];
     }
 
-    public function getVtuberName()
+    public function getVtuberInfo()
     {
         if (str_contains($this->link, "twitch.tv")) {
             $clientID = Application::$app->config["twitch"]["clientid"] ?? "";
@@ -77,53 +89,54 @@ class Vtubers extends DbModel
             $this->img = $response["items"][0]["snippet"]["thumbnails"]["default"]["url"];
             return;
         }
-        $this->username = "i got you bro";
-        $this->login = "i got you bro";
-        $this->img = "i got you bro";
     }
 
     public function isLive(string $login, string $link)
     {
-        if (str_contains($link, "twitch.tv")) {
-            $clientID = Application::$app->config["twitch"]["clientid"] ?? "";
-            $token = Application::$app->config["twitch"]["token"] ?? "";
+        // if (str_contains($link, "twitch.tv")) {
+        //     $clientID = Application::$app->config["twitch"]["clientid"] ?? "";
+        //     $token = Application::$app->config["twitch"]["token"] ?? "";
 
-            $url = "https://api.twitch.tv/helix/streams?user_login=$login";
+        //     $url = "https://api.twitch.tv/helix/streams?user_login=$login";
 
-            $ch = curl_init($url);
-            curl_setopt($ch, CURLOPT_URL, $url);
-            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-            curl_setopt($ch, CURLOPT_HTTPHEADER, array("Client-ID: $clientID", "Authorization: Bearer $token"));
+        //     $ch = curl_init($url);
+        //     curl_setopt($ch, CURLOPT_URL, $url);
+        //     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        //     curl_setopt($ch, CURLOPT_HTTPHEADER, array("Client-ID: $clientID", "Authorization: Bearer $token"));
 
-            $result = get_object_vars(json_decode(curl_exec($ch)));
-            curl_close($ch);
+        //     $result = get_object_vars(json_decode(curl_exec($ch)));
+        //     curl_close($ch);
 
-            return count($result["data"]) ? $result["data"] : [];
-        }
+        //     return count($result["data"]) ? $result["data"] : [];
+        // }
 
-        if (str_contains($link, "youtube.com")) {
-            $url = "https://www.youtube.com/channel/$login/live";
+        // if (str_contains($link, "youtube.com")) {
+        //     $url = "https://www.youtube.com/channel/$login/live";
 
-            $ch = curl_init($url);
-            curl_setopt($ch, CURLOPT_URL, $url);
-            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        //     $ch = curl_init($url);
+        //     curl_setopt($ch, CURLOPT_URL, $url);
+        //     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
-            $result = curl_exec($ch);
-            curl_close($ch);
+        //     $result = curl_exec($ch);
+        //     curl_close($ch);
 
-            $doc = new DOMDocument();
-            libxml_use_internal_errors(true);
-            $doc->loadHTML($result);
-            $length = $doc->getElementsByTagName('link')->length;
+        //     $doc = new DOMDocument();
+        //     libxml_use_internal_errors(true);
+        //     $doc->loadHTML($result);
 
-            for ($i = 0; $i < $length; $i++) {
-                $result = $doc->getElementsByTagName("link")->item($i)->getAttribute("href");
-                if (str_contains($result, "https://www.youtube.com/watch?v=")) {
-                    return [str_replace( "https://www.youtube.com/watch?v=", "",  $result)];
-                }
-            }
+        //     $result = $doc->getElementsByTagName("link");
+        //     $length = $result->length;
 
-            return [];
-        }
+        //     for ($i = 0; $i < $length; $i++) {
+        //         $tag = $result->item($i)->getAttribute("href");
+        //         if (str_contains($tag, "https://www.youtube.com/watch?v=")) {
+        //             return [str_replace("https://www.youtube.com/watch?v=", "",  $tag)];
+        //         }
+        //     }
+
+        //     unset($doc);
+        // }
+
+        return [];
     }
 }
index 28ab3df10c7a8dc66d3aff2deb6ff21bc2408006..ca1a395541d6dbce8caeefaae61b7531934bf915 100644 (file)
@@ -8,6 +8,7 @@ $dotenv = Dotenv\Dotenv::createImmutable(dirname(__DIR__));
 $dotenv->load();
 
 $config = [
+    "userClass" => \app\models\User::class,
     "db" => [
         "dsn" => $_ENV["DB_DSN"],
         "user" => $_ENV["DB_USER"],
index 1f13f44169e410dffaad4f27155373fb83e64475..00a44c8d6d63c4d617cb70aee7e49a8fc880dc0b 100644 (file)
@@ -1,3 +1,12 @@
+<?php
+
+use app\core\Application;
+
+echo " <pre>";
+var_dump(Application::$app->user);
+echo "</pre>";
+?>
+
 <!doctype html>
 <html lang="en">
 
index 74508138d50a531020f53793c0459da7625642d6..8a13a2cf7e64d68522303928d2ddeccd73a39e17 100644 (file)
@@ -10,27 +10,27 @@ if (!isset($_GET["id"])) {
     echo "<h2>Currently live</h2>";
     echo "<ul>";
     foreach ($params[0] as $idol) {
-        if (count($idol["vtuber"][1]) > 0)
-            echo "<li><a href='/live?id=" . $idol["vtuber"][0]["id"] . "'>" . ucfirst($idol["vtuber"][0]["username"]) . "</a></li>";
+        if (count($idol[1]) > 0)
+            echo "<li><a href='/live?id=" . $idol[0]["id"] . "'>" . ucfirst($idol[0]["username"]) . "</a></li>";
     }
     echo "</ul>";
 
     echo "<h2>Currently offline</h2>";
     echo "<ul>";
     foreach ($params[0] as $idol) {
-        if (count($idol["vtuber"][1]) == 0)
-            echo "<li><a href='/live?id=" . $idol["vtuber"][0]["id"] . "'>" . ucfirst($idol["vtuber"][0]["username"]) . "</a></li>";
+        if (count($idol[1]) == 0)
+            echo "<li><a href='/live?id=" . $idol[0]["id"] . "'>" . ucfirst($idol[0]["username"]) . "</a></li>";
     }
     echo "</ul>";
 } else {
     foreach ($params[0] as $vtuber) {
-        if ($_GET["id"] == $vtuber["vtuber"][0]["id"]) {
+        if ($_GET["id"] == $vtuber[0]["id"]) {
             echo "
     <div id=\"parent\">
     <div>
     <nav class=\"navbar bg-dark text-white\">
         <div class=\"container-fluid\">
-                <h1>" . ucfirst($vtuber["vtuber"][0]["username"]) . "</h1><img class=\"idolLogo\" src=\"" . $vtuber["vtuber"][0]["img"] . "\"/>
+                <h1>" . ucfirst($vtuber[0]["username"]) . "</h1><img class=\"idolLogo\" src=\"" . $vtuber[0]["img"] . "\"/>
         </div>
     </nav>
 
@@ -38,10 +38,10 @@ if (!isset($_GET["id"])) {
 
 <div id=\"child\">";
 
-            if (str_contains($vtuber["vtuber"][0]["link"], "twitch.tv")) {
-                echo "<iframe src=\"https://player.twitch.tv/?channel=".$vtuber["vtuber"][0]["login"]."&parent=localhost\" frameborder=\"0\" allowfullscreen=\"true\" scrolling=\"no\"></iframe>";
+            if (str_contains($vtuber[0]["link"], "twitch.tv")) {
+                echo "<iframe src=\"https://player.twitch.tv/?channel=".$vtuber[0]["login"]."&parent=localhost\" frameborder=\"0\" allowfullscreen=\"true\" scrolling=\"no\"></iframe>";
             } else {
-                echo "<iframe src=\"https://www.youtube.com/embed/".$vtuber["vtuber"][1][0]."\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>";
+                echo "<iframe src=\"https://www.youtube.com/embed/".$vtuber[1][0]."\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>";
             }
 
             echo "</div></div>";
index 5d48ec6a31fcc09d90ead45a6f06fe00484e451b..a4673b6b1187bf5e81f0d447fa9bc82c0ebbce57 100644 (file)
@@ -1,20 +1,10 @@
 <h1>Login page</h1>
 
 <div class="container">
-<form action="" method="post">
-  <div class="mb-3">
-    <label for="exampleInputEmail1" class="form-label">Email address</label>
-    <input name="email" type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
-    <div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
-  </div>
-  <div class="mb-3">
-    <label for="exampleInputPassword1" class="form-label">Password</label>
-    <input name="pass" type="password" class="form-control" id="exampleInputPassword1">
-  </div>
-  <div class="mb-3 form-check">
-    <input name="check" type="checkbox" class="form-check-input" id="exampleCheck1">
-    <label class="form-check-label" for="exampleCheck1">Check me out</label>
-  </div>
-  <button type="submit" class="btn btn-primary">Submit</button>
-</form>
+    <?php $form = app\core\forms\Form::begin("", "post"); ?>
+    <?php echo $form->field($model, "email"); ?>
+    <?php echo $form->field($model, "password")->passwordField(); ?>
+
+    <button type="submit" class="btn btn-primary">Submit</button>
+    <?php app\core\forms\Form::end(); ?>
 </div>