gata basic ul
This commit is contained in:
@@ -43,7 +43,6 @@ class AuthController extends Controller{
|
|||||||
$user->loadData($request->getBody());
|
$user->loadData($request->getBody());
|
||||||
|
|
||||||
if($user->validate() && $user->save()){
|
if($user->validate() && $user->save()){
|
||||||
Application::$app->session->setFlash('success', 'Thanks for registering');
|
|
||||||
$response->redirect('home');
|
$response->redirect('home');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
|
use app\core\Application;
|
||||||
use app\core\Controller;
|
use app\core\Controller;
|
||||||
use app\core\Request;
|
use app\core\Request;
|
||||||
|
use app\core\Response;
|
||||||
|
use app\models\ContactForm;
|
||||||
|
|
||||||
class SiteController extends Controller{
|
class SiteController extends Controller
|
||||||
public function handleContact(Request $request){
|
{
|
||||||
$body = $request->getBody();
|
public function contact(Request $request, Response $response)
|
||||||
return 'handling requested data';
|
{
|
||||||
|
$contact = new ContactForm();
|
||||||
|
|
||||||
|
if ($request->isPost()) {
|
||||||
|
$contact->loadData($request->getBody());
|
||||||
|
|
||||||
|
if ($contact->validate() && $contact->send()) {
|
||||||
|
Application::$app->session->setFlash('success', 'The form has been succesfully sent!');
|
||||||
|
var_dump($_SESSION['flash_messages']);
|
||||||
|
$response->redirect('contact');
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function contact(){
|
return $this->render('contact', [
|
||||||
return $this->render('contact');
|
'model' => $contact
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function home(){
|
return $this->render('contact', [
|
||||||
|
'model' => $contact
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function home()
|
||||||
|
{
|
||||||
$params = [
|
$params = [
|
||||||
'name' => "TheCodeholic"
|
'name' => "TheCodeholic"
|
||||||
];
|
];
|
||||||
@@ -22,11 +43,13 @@ class SiteController extends Controller{
|
|||||||
return $this->render('home', $params);
|
return $this->render('home', $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function profile(){
|
public function profile()
|
||||||
|
{
|
||||||
return $this->render('profile');
|
return $this->render('profile');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function _404(){
|
public function _404()
|
||||||
|
{
|
||||||
return $this->render('_404');
|
return $this->render('_404');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,7 @@ class Application
|
|||||||
public Database $db;
|
public Database $db;
|
||||||
public Session $session;
|
public Session $session;
|
||||||
public ?DbModel $user;
|
public ?DbModel $user;
|
||||||
|
public View $view;
|
||||||
|
|
||||||
public function __construct($rootPath, array $config)
|
public function __construct($rootPath, array $config)
|
||||||
{
|
{
|
||||||
@@ -28,6 +29,7 @@ class Application
|
|||||||
$this->request = new Request();
|
$this->request = new Request();
|
||||||
$this->response = new Response();
|
$this->response = new Response();
|
||||||
$this->router = new Router($this->request, $this->response);
|
$this->router = new Router($this->request, $this->response);
|
||||||
|
$this->view = new View();
|
||||||
|
|
||||||
$this->db = new Database($config['db']);
|
$this->db = new Database($config['db']);
|
||||||
$this->session = new Session();
|
$this->session = new Session();
|
||||||
@@ -78,12 +80,12 @@ class Application
|
|||||||
echo $this->router->resolve();
|
echo $this->router->resolve();
|
||||||
}catch(ForbiddenException $e){
|
}catch(ForbiddenException $e){
|
||||||
$this->response->setStatusCode(403);
|
$this->response->setStatusCode(403);
|
||||||
echo $this->router->renderView('_error', [
|
echo $this->view->renderView('_error', [
|
||||||
'exception' => $e
|
'exception' => $e
|
||||||
]);
|
]);
|
||||||
}catch(NotFoundException $e){
|
}catch(NotFoundException $e){
|
||||||
$this->response->setStatusCode(404);
|
$this->response->setStatusCode(404);
|
||||||
echo $this->router->renderView('_error', [
|
echo $this->view->renderView('_error', [
|
||||||
'exception' => $e
|
'exception' => $e
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class Controller{
|
|||||||
protected array $middlewares = [];
|
protected array $middlewares = [];
|
||||||
|
|
||||||
public function render($view, $params = []){
|
public function render($view, $params = []){
|
||||||
return Application::$app->router->renderView($view, $params);
|
return Application::$app->view->renderView($view, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setLayout($layout){
|
public function setLayout($layout){
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace app\core;
|
namespace app\core;
|
||||||
|
|
||||||
use app\core\exceptions\NotFoundException;
|
use app\core\exceptions\NotFoundException;
|
||||||
|
|
||||||
class Router
|
class Router
|
||||||
@@ -25,11 +26,6 @@ class Router
|
|||||||
$this->routes['post'][$path] = $callback;
|
$this->routes['post'][$path] = $callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
in aceasta functie se identifica path ul catre fisier, metoda (GET/POST) si se identifica un "routes" callback ul (in general controller ul) pe care trebuie sa l returneze
|
|
||||||
astfel, in call_user_function, se ofera clasa de tip constructor si request ul de la user ca dupa controller ul sa se ocupe de restul
|
|
||||||
*/
|
|
||||||
|
|
||||||
public function resolve()
|
public function resolve()
|
||||||
{
|
{
|
||||||
$path = $this->request->getPath();
|
$path = $this->request->getPath();
|
||||||
@@ -40,11 +36,6 @@ class Router
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($callback)) {
|
|
||||||
return $this->renderView($callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($callback)) {
|
|
||||||
$controller = new $callback[0]();
|
$controller = new $callback[0]();
|
||||||
Application::$app->controller = $controller;
|
Application::$app->controller = $controller;
|
||||||
$controller->action = $callback[1];
|
$controller->action = $callback[1];
|
||||||
@@ -53,48 +44,7 @@ class Router
|
|||||||
foreach ($controller->getMiddlewares() as $middleware) {
|
foreach ($controller->getMiddlewares() as $middleware) {
|
||||||
$middleware->execute();
|
$middleware->execute();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return call_user_func($callback, $this->request, $this->response);
|
return call_user_func($callback, $this->request, $this->response);
|
||||||
}
|
}
|
||||||
|
|
||||||
//layout ne va ajuta sa identificam ce fel de layout trebuie sa aiba pagina pe care o trimitem (elemente extra in afara de continut: navbar, elemente din baza de date etc)
|
|
||||||
protected function layoutContent()
|
|
||||||
{
|
|
||||||
$layout = Application::$app->layout;
|
|
||||||
if (Application::$app->controller) {
|
|
||||||
$layout = Application::$app->controller->layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
ob_start();
|
|
||||||
include_once Application::$ROOT_DIR . "/views/layouts/$layout.php";
|
|
||||||
return ob_get_clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function renderView($view, $params = [])
|
|
||||||
{
|
|
||||||
$layoutContent = $this->layoutContent();
|
|
||||||
$viewContent = $this->renderOnlyView($view, $params);
|
|
||||||
|
|
||||||
return str_replace('{{content}}', $viewContent, $layoutContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function renderContent($viewContent)
|
|
||||||
{
|
|
||||||
$layoutContent = $this->layoutContent();
|
|
||||||
return str_replace('{{content}}', $viewContent, $layoutContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderOnlyView($view, $params)
|
|
||||||
{
|
|
||||||
foreach ($params as $key => $value) {
|
|
||||||
$$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ob_start();
|
|
||||||
include_once Application::$ROOT_DIR . "/views/$view.php";
|
|
||||||
return ob_get_clean();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -4,14 +4,12 @@ namespace app\core;
|
|||||||
|
|
||||||
class Session{
|
class Session{
|
||||||
protected const FLASH_KEY = 'flash_messages';
|
protected const FLASH_KEY = 'flash_messages';
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
session_start();
|
session_start();
|
||||||
$flashMessages = $_SESSION[self::FLASH_KEY] ?? [];
|
foreach($_SESSION[self::FLASH_KEY] as $key => &$flashMessage){
|
||||||
foreach($flashMessages as $key => &$flashMessage){
|
|
||||||
$flashMessage['remove'] = 'true';
|
$flashMessage['remove'] = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
$_SESSION[self::FLASH_KEY] = $flashMessages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFlash($key, $message){
|
public function setFlash($key, $message){
|
||||||
@@ -30,7 +28,7 @@ class Session{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function get($key){
|
public function get($key){
|
||||||
return $_SESSION[$key] ?? false;
|
return $_SESSION[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function remove($key){
|
public function remove($key){
|
||||||
@@ -40,7 +38,7 @@ class Session{
|
|||||||
public function __destruct(){
|
public function __destruct(){
|
||||||
$flashMessages = $_SESSION[self::FLASH_KEY] ?? [];
|
$flashMessages = $_SESSION[self::FLASH_KEY] ?? [];
|
||||||
foreach($flashMessages as $key => &$flashMessage){
|
foreach($flashMessages as $key => &$flashMessage){
|
||||||
if($flashMessage['remove']){
|
if($flashMessage['remove'] == 'true'){
|
||||||
unset($flashMessages[$key]);
|
unset($flashMessages[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\core;
|
||||||
|
|
||||||
|
class View{
|
||||||
|
public string $title = '';
|
||||||
|
|
||||||
|
protected function layoutContent()
|
||||||
|
{
|
||||||
|
$layout = Application::$app->layout;
|
||||||
|
if (Application::$app->controller) {
|
||||||
|
$layout = Application::$app->controller->layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
include_once Application::$ROOT_DIR . "/views/layouts/$layout.php";
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function renderView($view, $params = [])
|
||||||
|
{
|
||||||
|
$viewContent = $this->renderOnlyView($view, $params);
|
||||||
|
$layoutContent = $this->layoutContent();
|
||||||
|
|
||||||
|
return str_replace('{{content}}', $viewContent, $layoutContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderContent($viewContent)
|
||||||
|
{
|
||||||
|
$layoutContent = $this->layoutContent();
|
||||||
|
return str_replace('{{content}}', $viewContent, $layoutContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderOnlyView($view, $params)
|
||||||
|
{
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$$key = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
include_once Application::$ROOT_DIR."/views/$view.php";
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\core\form;
|
||||||
|
use app\core\Model;
|
||||||
|
|
||||||
|
abstract class BaseField
|
||||||
|
{
|
||||||
|
public Model $model;
|
||||||
|
public string $attribute;
|
||||||
|
|
||||||
|
public function __construct(Model $model, string $attribute)
|
||||||
|
{
|
||||||
|
$this->model = $model;
|
||||||
|
$this->attribute = $attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function renderInput(): string;
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return sprintf('
|
||||||
|
<div class="mb-3">
|
||||||
|
<label>%s</label>
|
||||||
|
%s
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
%s
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
',
|
||||||
|
$this->model->labels()[$this->attribute] ?? $this->attribute,
|
||||||
|
$this->renderInput(),
|
||||||
|
$this->model->getFirstError($this->attribute)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,8 +13,8 @@ class Form{
|
|||||||
echo '</form>';
|
echo '</form>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function field(Model $model, $attribute){
|
public function inputField(Model $model, $attribute){
|
||||||
return new Field($model, $attribute);
|
return new InputField($model, $attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function button(){
|
public function button(){
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\core\form;
|
||||||
|
|
||||||
|
use app\core\Model;
|
||||||
|
|
||||||
|
class InputField extends BaseField
|
||||||
|
{
|
||||||
|
public const TYPE_TEXT = 'text';
|
||||||
|
public const TYPE_PASSWORD = 'password';
|
||||||
|
|
||||||
|
public string $type;
|
||||||
|
|
||||||
|
public function __construct(Model $model, string $attribute)
|
||||||
|
{
|
||||||
|
$this->type = self::TYPE_TEXT;
|
||||||
|
parent::__construct($model, $attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function passwordField()
|
||||||
|
{
|
||||||
|
$this->type = self::TYPE_PASSWORD;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderInput(): string
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'<input type="%s" name="%s" value="%s" class="form-control%s">',
|
||||||
|
$this->type,
|
||||||
|
$this->attribute,
|
||||||
|
$this->model->{$this->attribute},
|
||||||
|
$this->model->hasError($this->attribute) ? ' is invalid' : ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\core\form;
|
||||||
|
|
||||||
|
class TextareaField extends BaseField{
|
||||||
|
public function renderInput(): string{
|
||||||
|
return sprintf('<textarea name=%s class=form-control%s>%s</textarea>',
|
||||||
|
$this->attribute,
|
||||||
|
$this->model->hasError($this->attribute) ? ' is invalid' : '',
|
||||||
|
$this->model->{$this->attribute}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ $app->router->get('/home', [SiteController::class, 'home']);
|
|||||||
$app->router->get('/_404', [SiteController::class, '_404']);
|
$app->router->get('/_404', [SiteController::class, '_404']);
|
||||||
|
|
||||||
$app->router->get('/contact', [SiteController::class, 'contact']);
|
$app->router->get('/contact', [SiteController::class, 'contact']);
|
||||||
$app->router->post('/contact', [SiteController::class, 'handleContact']);
|
$app->router->post('/contact', [SiteController::class, 'contact']);
|
||||||
|
|
||||||
$app->router->get('/login', [AuthController::class, 'login']);
|
$app->router->get('/login', [AuthController::class, 'login']);
|
||||||
$app->router->post('/login', [AuthController::class, 'login']);
|
$app->router->post('/login', [AuthController::class, 'login']);
|
||||||
@@ -36,4 +36,6 @@ $app->router->post('/profile', [AuthController::class, 'profile']);
|
|||||||
|
|
||||||
$app->router->get('/logout', [AuthController::class, 'logout']);
|
$app->router->get('/logout', [AuthController::class, 'logout']);
|
||||||
|
|
||||||
|
$app->router->get('/login/{id}', [SiteController::class, 'login']);
|
||||||
|
|
||||||
$app->run();
|
$app->run();
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
use app\core\Model;
|
||||||
|
|
||||||
|
class ContactForm extends Model{
|
||||||
|
public string $subject = '';
|
||||||
|
public string $body = '';
|
||||||
|
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'subject' => [self::RULE_REQUIRED],
|
||||||
|
'body' => [self::RULE_REQUIRED]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function labels(): array{
|
||||||
|
return [
|
||||||
|
'subject' => 'Enter your subject',
|
||||||
|
'body' => 'Enter the body'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,12 @@
|
|||||||
<h1>Contact</h1>
|
<?php
|
||||||
|
use app\core\form\Form;
|
||||||
|
use app\core\form\TextareaField;
|
||||||
|
$this->title = 'Contact';
|
||||||
|
|
||||||
<form action="" method="post">
|
$form = Form::begin('', 'post');
|
||||||
<div class="mb-3">
|
echo $form->inputField($model, 'subject');
|
||||||
<label>Subject</label>
|
echo new TextareaField($model, 'body');
|
||||||
<input type="text" name="subject" class="form-control">
|
echo $form->button();
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
Form::end();
|
||||||
<label>Email</label>
|
?>
|
||||||
<input type="text" name="email" class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label>Body</label>
|
|
||||||
<textarea name="body" class="form-control"></textarea>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
|
||||||
</form>
|
|
||||||
@@ -1,2 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
$this->title = 'Home';
|
||||||
|
?>
|
||||||
|
|
||||||
<h1>Home</h1>
|
<h1>Home</h1>
|
||||||
<h2> Welcome <?php echo $name;?> to our site!</h2>
|
<h2> Welcome <?php echo $name;?> to our site!</h2>
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
use app\core\Application;
|
||||||
|
?>
|
||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Bootstrap demo</title>
|
<title><?php echo $this->title; ?></title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -42,6 +46,12 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<?php
|
||||||
|
$flashMessage = Application::$app->session->getFlash('success');
|
||||||
|
if($flashMessage){
|
||||||
|
echo $flashMessage;
|
||||||
|
}
|
||||||
|
?>
|
||||||
{{content}}
|
{{content}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
<h1>Login</h1>
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
use app\core\form\Form;
|
use app\core\form\Form;
|
||||||
/* @var $model \app\models\User */
|
$this->title='Login';
|
||||||
|
|
||||||
$form = Form::begin('', 'post');
|
$form = Form::begin('', 'post');
|
||||||
|
|
||||||
echo $form->field($model, 'email');
|
echo $form->InputField($model, 'email');
|
||||||
echo $form->field($model, 'password')->passwordField();
|
echo $form->inputField($model, 'password')->passwordField();
|
||||||
|
|
||||||
echo $form->button();
|
echo $form->button();
|
||||||
|
|
||||||
Form::end()
|
Form::end()
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<h1>Login</h1>
|
||||||
@@ -1 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$this->title = 'Profile';
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
<h1>Profile</h1>
|
<h1>Profile</h1>
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
<h1>Create An Account</h1>
|
|
||||||
<?php
|
<?php
|
||||||
use app\core\form\Form;
|
use app\core\form\Form;
|
||||||
/* @var $model \app\models\User */
|
$this->title = 'Register';
|
||||||
|
|
||||||
$form = Form::begin('', 'post');
|
$form = Form::begin('', 'post');
|
||||||
|
|
||||||
echo $form->field($model, 'firstname');
|
echo $form->inputField($model, 'firstname');
|
||||||
echo $form->field($model, 'lastname');
|
echo $form->inputField($model, 'lastname');
|
||||||
echo $form->field($model, 'email');
|
echo $form->inputField($model, 'email');
|
||||||
echo $form->field($model, 'password')->passwordField();
|
echo $form->inputField($model, 'password')->passwordField();
|
||||||
|
|
||||||
echo $form->button();
|
echo $form->button();
|
||||||
|
|
||||||
Form::end()
|
Form::end()
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<h1>Create An Account</h1>
|
||||||
|
|||||||
Reference in New Issue
Block a user