Skip to content

Commit 54331ee

Browse files
committed
Complete second day, 04/07
1 parent 3641a49 commit 54331ee

File tree

11 files changed

+206
-43
lines changed

11 files changed

+206
-43
lines changed

controllers/AuthController.php

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace app\controllers;
44

5+
use app\core\Application;
56
use app\core\Controller;
67
use app\core\Request;
7-
use app\models\RegisterModel;
8+
use app\models\User;
89

910
class AuthController extends Controller
1011
{
@@ -21,23 +22,19 @@ public function register(Request $request)
2122

2223
$errors = [];
2324

24-
$registerModel = new RegisterModel();
25+
$userModel = new User();
2526

2627
if ($request->isPost()) {
27-
$registerModel->loadData($request->getBody());
28+
$userModel->loadData($request->getBody());
2829

29-
if ($registerModel->validation()/* && $registerModel->register()*/) {
30-
return 'Success';
30+
if ($userModel->validation() && $userModel->save()) {
31+
Application::$app->session->setFlash('success', 'Thanks for registering!');
32+
Application::$app->response->redirect('/');
3133
}
32-
33-
34-
return $this->render('register',[
35-
'model' => $registerModel,
36-
]);
3734
}
3835

3936
return $this->render('register',[
40-
'model' => $registerModel,
37+
'model' => $userModel,
4138
]);
4239
}
4340
}

core/Application.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class Application
1010
public Response $response;
1111
public Controller $controller;
1212
public Database $db;
13+
public Session $session;
1314

1415
public static Application $app;
1516

@@ -20,7 +21,7 @@ public function __construct($rootDir, array $config)
2021
$this->request = new Request();
2122
$this->response = new Response();
2223
$this->router = new Router($this->request, $this->response);
23-
24+
$this->session = new Session();
2425
$this->db = new Database($config['db']);
2526
}
2627

core/Database.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ public function __construct(array $config)
1616
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
1717
}
1818

19+
public function prepare(string $sql)
20+
{
21+
return $this->pdo->prepare($sql);
22+
}
23+
1924
public function applyMigrations()
2025
{
2126
$this->createMigrationsTable();

core/DbModel.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace app\core;
4+
5+
abstract class DbModel extends Model
6+
{
7+
abstract public function tableName(): string;
8+
9+
abstract public function attributes(): array;
10+
11+
12+
public function save()
13+
{
14+
$tableName = $this->tableName();
15+
$attributes = $this->attributes();
16+
17+
$params = array_map(fn($attr) => ":$attr", $attributes);
18+
19+
$statement = self::prepare("
20+
INSERT INTO $tableName(" . implode(', ', $attributes) . ")
21+
VALUES(" . implode(', ', $params) . ")
22+
");
23+
24+
foreach ($attributes as $attribute)
25+
$statement->bindValue(":$attribute", $this->{$attribute});
26+
27+
$statement->execute();
28+
29+
return true;
30+
}
31+
32+
public static function prepare(string $sql)
33+
{
34+
return Application::$app->db->pdo->prepare($sql);
35+
}
36+
37+
}

core/Model.php

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ abstract class Model
1010
public const RULE_MIN = 'min';
1111
public const RULE_MAX = 'max';
1212
public const RULE_MATCH = 'match';
13+
public const RULE_UNIQUE = 'unique';
1314

1415
public const ERROR_MASSAGES = [
1516
self::RULE_REQUIRED => 'This field is required!',
16-
self::RULE_EMAIL => 'This field must be valid email address',
17-
self::RULE_MIN => 'Min length of this field must be bigger than {min}',
18-
self::RULE_MAX => 'Max length of this field must be less than {max}',
19-
self::RULE_MATCH => 'This field must be the same as {match}',
17+
self::RULE_EMAIL => 'This field must be valid email address!',
18+
self::RULE_MIN => 'Min length of this field must be bigger than {min}!',
19+
self::RULE_MAX => 'Max length of this field must be less than {max}!',
20+
self::RULE_MATCH => 'This field must be the same as {match}!',
21+
self::RULE_UNIQUE => 'Record with this {attribute} is already exists!'
2022
];
2123

2224

@@ -55,6 +57,20 @@ public function validation()
5557

5658
if ($ruleName === self::RULE_MATCH && $value !== $this->{$rule['match']})
5759
$this->addError($attribute, self::RULE_MATCH, $rule);
60+
61+
if ($ruleName === self::RULE_UNIQUE) {
62+
$className = $rule['class'];
63+
$uniqueAttr = $rule['attribute'] ?? $attribute;
64+
$tableName = $className::tableName();
65+
$statement = Application::$app->db->prepare("
66+
SELECT * FROM $tableName WHERE $uniqueAttr = :$uniqueAttr;
67+
");
68+
$statement->bindValue(":$uniqueAttr", $value);
69+
$statement->execute();
70+
$record = $statement->fetchObject();
71+
if ($record)
72+
$this->addError($attribute, self::RULE_UNIQUE, $rule);
73+
}
5874
}
5975
}
6076

@@ -66,7 +82,7 @@ public function addError(string $attribute, string $rule, $params = [])
6682
$massage = self::ERROR_MASSAGES[$rule] ?? '';
6783

6884
foreach ($params as $key => $value) {
69-
$massage = str_replace('{' . $key . '}', $value, $massage);
85+
$massage = str_replace('{' . $key . '}', $this->getLabel($value), $massage);
7086
}
7187

7288
$this->errors[$attribute][] = $massage;
@@ -82,4 +98,15 @@ public function getFirstError($attribute)
8298
return $this->errors[$attribute][0] ?? '';
8399
}
84100

101+
102+
public function labels(): array
103+
{
104+
return [];
105+
}
106+
107+
public function getLabel($attribute): string
108+
{
109+
return $this->labels()[$attribute] ?? $attribute;
110+
}
111+
85112
}

core/Response.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@
22

33
namespace app\core;
44

5+
use app\traits\ValidatePath;
6+
57
class Response
68
{
9+
use ValidatePath;
710

811
public function setStatusCode(int $code)
912
{
1013
http_response_code($code);
1114
}
15+
16+
public function redirect($path)
17+
{
18+
$path = $this->validatePath($path);
19+
20+
header('Location: ' . $path);
21+
}
1222
}

core/Session.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace app\core;
4+
5+
class Session
6+
{
7+
protected const FLASH_KEY = 'flash_massage';
8+
9+
public function __construct()
10+
{
11+
session_start();
12+
13+
// Mark sessions to be removed
14+
foreach ($_SESSION[self::FLASH_KEY] ?? [] as $key => $flashMassage)
15+
$_SESSION[self::FLASH_KEY][$key]['remove'] = true;
16+
}
17+
18+
public function __destruct()
19+
{
20+
// Iterate over to remove marked sessions
21+
foreach ($_SESSION[self::FLASH_KEY] ?? [] as $key => $flashMassage)
22+
if ($flashMassage['remove'])
23+
unset($_SESSION[self::FLASH_KEY][$key]);
24+
}
25+
26+
public function setFlash($key, $massage)
27+
{
28+
$_SESSION[self::FLASH_KEY][$key] = [
29+
'removed' => false,
30+
'value' => $massage,
31+
];
32+
}
33+
34+
public function getFlash($key)
35+
{
36+
return $_SESSION[self::FLASH_KEY][$key]['value'];
37+
}
38+
}

core/form/Field.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function __toString()
3232
<div class="invalid-feedback">%s</div>
3333
</div>
3434
',
35-
$this->attribute,
35+
$this->model->getLabel($this->attribute),
3636
$this->type,
3737
$this->attribute,
3838
$this->model->{$this->attribute},

models/RegisterModel.php

Lines changed: 0 additions & 25 deletions
This file was deleted.

models/User.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace app\models;
4+
5+
use app\core\DbModel;
6+
7+
class User extends DbModel
8+
{
9+
const STATUS_INACTIVE = 0;
10+
const STATUS_ACTIVE = 1;
11+
const STATUS_DELETED = 2;
12+
13+
public string $firstname = '';
14+
public string $lastname = '';
15+
public string $email = '';
16+
public int $status = self::STATUS_INACTIVE;
17+
public string $password = '';
18+
public string $confirmPassword = '';
19+
20+
public function labels(): array
21+
{
22+
return [
23+
'firstname' => 'First Name',
24+
'lastname' => 'Last Name',
25+
'email' => 'Email',
26+
'password' => 'Password',
27+
'confirmPassword' => 'Confirm Password',
28+
];
29+
}
30+
31+
public function rules(): array
32+
{
33+
return [
34+
'firstname' => [self::RULE_REQUIRED],
35+
'lastname' => [self::RULE_REQUIRED],
36+
'email' => [self::RULE_REQUIRED, self::RULE_EMAIL,
37+
[self::RULE_UNIQUE, 'class' => self::class, 'attribute' => 'email']],
38+
'password' => [self::RULE_REQUIRED, [self::RULE_MIN, 'min' => 8], [self::RULE_MAX, 'max' => 24]],
39+
'confirmPassword' => [self::RULE_REQUIRED, [self::RULE_MATCH, 'match' => 'password']],
40+
];
41+
}
42+
43+
public function attributes(): array
44+
{
45+
return ['firstname', 'lastname', 'email', 'status', 'password'];
46+
}
47+
48+
public function tableName(): string
49+
{
50+
return 'users';
51+
}
52+
53+
54+
public function save()
55+
{
56+
$this->status = self::STATUS_INACTIVE;
57+
58+
$this->password = password_hash($this->password, PASSWORD_DEFAULT);
59+
60+
return parent::save();
61+
}
62+
63+
}

views/layouts/app.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2+
<?php use app\core\Application; ?>
3+
14
<!doctype html>
25
<html lang="en">
36
<head>
@@ -38,6 +41,13 @@
3841

3942

4043
<div class="container">
44+
45+
<?php if (Application::$app->session->getFlash('success')): ?>
46+
<div class="alert alert-success">
47+
<?php echo Application::$app->session->getFlash('success') ?>
48+
</div>
49+
<?php endif; ?>
50+
4151
{{content}}
4252
</div>
4353

0 commit comments

Comments
 (0)