Плотников Роман Вячеславович 3 anos atrás
pai
commit
d05eece36e

+ 22 - 2
app/Controller/Site.php

@@ -3,6 +3,7 @@
 namespace Controller;
 
 use Src\View;
+use Src\Auth\Auth;
 use Src\Request;
 use Model\Post;
 use Model\User;
@@ -23,8 +24,27 @@ class Site
     public function signup(Request $request)
     {
         if ($request->method === "POST" && User::create($request->all())) {
-            return new View('site.signup', ['message' => 'Вы успешно зарегистрированы']);
+            app()->route->redirect('/hello');
         }
-        return (new View())->render('site.signup');
+        return new View('site.signup');
+    }
+    public function login(Request $request): string
+    {
+        //Если просто обращение к странице, то отобразить форму
+        if ($request->method === 'GET') {
+            return new View('site.login');
+        }
+        //Если удалось аутентифицировать пользователя, то редирект
+        if (Auth::attempt($request->all())) {
+            app()->route->redirect('/hello');
+        }
+        //Если аутентификация не удалась, то сообщение об ошибке
+        return new View('site.login', ['message' => 'Неправильные логин или пароль']);
+    }
+
+    public function logout(): void
+    {
+        Auth::logout();
+        app()->route->redirect('/hello');
     }
 }

+ 17 - 1
app/Model/User.php

@@ -4,8 +4,9 @@ namespace Model;
 
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Src\Auth\IdentityInterface;
 
-class User extends Model {
+class User extends Model implements IdentityInterface{
     use HasFactory;
 
     public $timestamps = false;
@@ -22,4 +23,19 @@ class User extends Model {
             $user->save();
         });
     }
+
+    public function findIdentity(int $id)
+    {
+        return self::where('id', $id)->first();
+    }
+
+    public function attemptIdentity(array $credentials)
+    {
+        return self::where(['login' => $credentials['login'], 'password' => md5($credentials['password'])])->first();
+    }
+
+    public function getId(): int
+    {
+        return $this->id;
+    }
 }

+ 7 - 0
config/app.php

@@ -0,0 +1,7 @@
+<?php
+return [
+   //Класс аутентификации
+   'auth' => \Src\Auth\Auth::class,
+   //Клас пользователя
+   'identity'=>\Model\User::class
+];

+ 22 - 7
core/Src/Application.php

@@ -6,31 +6,47 @@ use Error;
 use Illuminate\Container\Container;
 use Illuminate\Events\Dispatcher;
 use Illuminate\Database\Capsule\Manager as Capsule;
+use Src\Auth\Auth;
 
 class Application
 {
     private Settings $settings;
     private Route $route;
     private Capsule $dbManager;
-
+    private Auth $auth;
     public function __construct(Settings $settings)
     {
+        //Привязываем класс со всеми настройками приложения
         $this->settings = $settings;
-        $this->route = new Route();
+        //Привязываем класс маршрутизации с установкой префикса
+        $this->route = new Route($this->settings->getRootPath());
+        //Создаем класс менеджера для базы данных
         $this->dbManager = new Capsule();
+        //Создаем класс для аутентификации на основе настроек приложения
+        $this->auth = new $this->settings->app['auth'];
+
+        //Настройка для работы с базой данных
+        $this->dbRun();
+        //Инициализация класса пользователя на основе настроек приложения
+        $this->auth::init(new $this->settings->app['identity']);
     }
 
     public function __get($key)
     {
-        if ($key === 'settings') {
-            return $this->settings;
+        switch ($key) {
+            case 'settings':
+                return $this->settings;
+            case 'route':
+                return $this->route;
+            case 'auth':
+                return $this->auth;
         }
         throw new Error('Accessing a non-existent property');
     }
 
     private function dbRun()
     {
-        $this->dbManager->addConnection($this->settings->getDbSettings());
+        $this->dbManager->addConnection($this->settings->getDbSetting());
         $this->dbManager->setEventDispatcher(new Dispatcher(new Container));
         $this->dbManager->setAsGlobal();
         $this->dbManager->bootEloquent();
@@ -38,8 +54,7 @@ class Application
 
     public function run(): void
     {
-        $this->dbRun();
-        $this->route->setPrefix($this->settings->getRootPath());
+        //Запуск маршрутизации
         $this->route->start();
     }
 }

+ 60 - 0
core/Src/Auth/Auth.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace Src\Auth;
+
+use Src\Session;
+
+class Auth
+{
+    //Свойство для хранения любого класса, реализующего интерфейс IdentityInterface
+    private static IdentityInterface $user;
+
+    //Инициализация класса пользователя
+    public static function init(IdentityInterface $user): void
+    {
+        self::$user = $user;
+        if (self::user()) {
+            self::login(self::user());
+        }
+    }
+
+    //Вход пользователя по модели
+    public static function login(IdentityInterface $user): void
+    {
+        self::$user = $user;
+        Session::set('id', self::$user->getId());
+    }
+
+    //Аутентификация пользователя и вход по учетным данным
+    public static function attempt(array $credentials): bool
+    {
+        if ($user = self::$user->attemptIdentity($credentials)) {
+            self::login($user);
+            return true;
+        }
+        return false;
+    }
+
+    //Возврат текущего аутентифицированного пользователя
+    public static function user()
+    {
+        $id = Session::get('id') ?? 0;
+        return self::$user->findIdentity($id);
+    }
+
+    //Проверка является ли текущий пользователь аутентифицированным
+    public static function check(): bool
+    {
+        if (self::user()) {
+            return true;
+        }
+        return false;
+    }
+
+    //Выход текущего пользователя
+    public static function logout(): bool
+    {
+        Session::clear('id');
+        return true;
+    }
+}

+ 9 - 0
core/Src/Auth/IdentityInterface.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace Src\Auth;
+
+interface IdentityInterface {
+    public function findIdentity(int $id);
+    public function getId(): int;
+    public function attemptIdentity(array $credentials);
+}

+ 15 - 7
core/Src/Request.php

@@ -4,7 +4,8 @@ namespace Src;
 
 use Error;
 
-class Request {
+class Request
+{
     protected array $body;
     public string $method;
     public array $headers;
@@ -16,15 +17,22 @@ class Request {
         $this->headers = getallheaders() ?? [];
     }
 
-    public function set($field, $value): void {
+    public function all(): array
+    {
+        return $this->body + $this->files();
+    }
+
+    public function set($field, $value): void
+    {
         $this->body[$field] = $value;
     }
 
-    public function get($field) {
+    public function get($field)
+    {
         return $this->body[$field];
     }
-
-    public function files(): array {
+    public function files(): array
+    {
         return $_FILES;
     }
 
@@ -33,6 +41,6 @@ class Request {
         if (array_key_exists($key, $this->body)) {
             return $this->body[$key];
         }
-        throw new Error('Acessing a non-existent property');
+        throw new Error('Accessing a non-existent property');
     }
-}
+}

+ 17 - 1
core/Src/Route.php

@@ -21,6 +21,22 @@ class Route
         }
     }
 
+    public function redirect(string $url): void
+    {
+        header('Location: ' . $this->getUrl($url));
+    }
+
+    public function getUrl(string $url): string
+    {
+        return self::$prefix . $url;
+    }
+
+    public function __construct(string $prefix = '')
+    {
+        self::setPrefix($prefix);
+    }
+
+
     public function start(): void
     {
         $path = explode('?', $_SERVER['REQUEST_URI'])[0];
@@ -43,4 +59,4 @@ class Route
 
         call_user_func([new $class, $action], new Request());
     }
-}
+}

+ 21 - 0
core/Src/Session.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Src;
+
+class Session
+{
+    public static function set($name, $value): void
+    {
+        $_SESSION[$name] = $value;
+    }
+
+    public static function get($name)
+    {
+        return $_SESSION[$name] ?? null;
+    }
+
+    public static function clear($name)
+    {
+        unset($_SESSION[$name]);
+    }
+}

+ 1 - 1
core/Src/Settings.php

@@ -31,7 +31,7 @@ class Settings
         return '/' . $this->path['views'] ?? '';
     }
 
-    public function getDbSettings(): array {
+    public function getDbSetting(): array {
         return $this->db ?? [];
     }
 }

+ 7 - 1
core/bootstrap.php

@@ -19,6 +19,12 @@ function getConfigs(string $path = DIR_CONFIG): array
 }
 
 require_once __DIR__ . '/../routes/web.php';
+$app = new Src\Application(new Src\Settings(getConfigs()));
 
-return new Src\Application(new Src\Settings(getConfigs()));
+//Функция возвращает глобальный экземпляр приложения
+function app() {
+   global $app;
+   return $app;
+}
 
+return $app;

+ 4 - 2
routes/web.php

@@ -2,6 +2,8 @@
 
 use Src\Route;
 
-Route::add('index', [Controller\Site::class, 'index']);
+Route::add('go', [Controller\Site::class, 'index']);
 Route::add('hello', [Controller\Site::class, 'hello']);
-Route::add('signup', [Controller\Site::class, 'signup']);
+Route::add('signup', [Controller\Site::class, 'signup']);
+Route::add('login', [Controller\Site::class, 'login']);
+Route::add('logout', [Controller\Site::class, 'logout']);

+ 26 - 8
views/layouts/main.php

@@ -1,17 +1,35 @@
 <!doctype html>
 <html lang="en">
+
 <head>
     <meta charset="UTF-8">
-    <meta name="viewport"
-          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
-    <title>Main site</title>
+    <title>Pop it MVC</title>
 </head>
-<body>
 
-<div>
-    <?= $content ?? ''; ?>
-</div>
+<body>
+    <header>
+        <nav>
+            <a href="<?= app()->route->getUrl('/hello') ?>">Главная</a>
+            <?php
+            if (!app()->auth::check()) :
+            ?>
+                <a href="<?= app()->route->getUrl('/login') ?>">Вход</a>
+                <a href="<?= app()->route->getUrl('/signup') ?>">Регистрация</a>
+            <?php
+            else :
+            ?>
+                <a href="<?= app()->route->getUrl('/logout') ?>">Выход (<?= app()->auth::user()->name ?>)</a>
+            <?php
+            endif;
+            ?>
+        </nav>
+    </header>
+    <main>
+        <?= $content ?? '' ?>
+    </main>
 
 </body>
-</html>
+
+</html>

+ 13 - 0
views/site/login.php

@@ -0,0 +1,13 @@
+<h2>Авторизация</h2>
+<h3><?= $message ?? ''; ?></h3>
+
+<h3><?= app()->auth->user()->name ?? ''; ?></h3>
+<?php
+if (!app()->auth::check()):
+   ?>
+   <form method="post">
+       <label>Логин <input type="text" name="login"></label>
+       <label>Пароль <input type="password" name="password"></label>
+       <button>Войти</button>
+   </form>
+<?php endif;