Skip to content

Commit

Permalink
pridanie frameworku
Browse files Browse the repository at this point in the history
  • Loading branch information
Filip10 committed Nov 21, 2023
1 parent d9f0aa5 commit 43a30d7
Show file tree
Hide file tree
Showing 44 changed files with 2,162 additions and 2 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/php-syntax.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: PHP check syntax errors

on:
push:
branches: [ "**" ]
pull_request:
branches: [ "master" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: overtrue/[email protected]
- uses: php-actions/phpcs@v1
with:
php_version: 8.2
path: App/
standard: PSR12
args: "--runtime-set ignore_warnings_on_exit 1"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea
2 changes: 1 addition & 1 deletion .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .idea/php.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 149 additions & 0 deletions App/App.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<?php

namespace App;

use App\Config\Configuration;
use App\Core\HTTPException;
use App\Core\IAuthenticator;
use App\Core\DB\Connection;
use App\Core\LinkGenerator;
use App\Core\Request;
use App\Core\Responses\RedirectResponse;
use App\Core\Responses\Response;
use App\Core\Router;

/**
* Class App
* Main Application class
* @package App
*/
class App
{
/**
* @var Router
*/
private $router;
/**
* @var Request
*/
private Request $request;
private LinkGenerator $linkGenerator;
private ?IAuthenticator $auth;

/**
* App constructor
*/
public function __construct()
{
$this->router = new Router();
$this->request = new Request();
$this->linkGenerator = new LinkGenerator($this->request, $this->router);

// Check if there is an authenticator
if (defined('\\App\\Config\\Configuration::AUTH_CLASS')) {
//$authClass = Configuration::AUTH_CLASS;
$this->auth = new (Configuration::AUTH_CLASS)();
} else {
$this->auth = null;
}
}

/**
* Runs the application
* @throws \Exception
*/
public function run()
{
ob_start();

try {
// get a controller and action from URL
$this->router->processURL();

// inject app into Controller
call_user_func([$this->router->getController(), 'setApp'], $this);

// try to authorize action
if ($this->router->getController()->authorize($this->router->getAction())) {
// call appropriate method of the controller class
$response = call_user_func([$this->router->getController(), $this->router->getAction()]);

// return view to user
if ($response instanceof Response) {
$response->send();
} else {
throw new \Exception("Action {$this->router->getFullControllerName()}::{$this->router->getAction()} didn't return an instance of Response.");
}
} else {
if ($this->auth->isLogged() || !defined('\\App\\Config\\Configuration::LOGIN_URL')) {
throw new HTTPException(403);
} else {
(new RedirectResponse(Configuration::LOGIN_URL))->send();
}
}
} catch (\Throwable $exception) {
//Clears partially rendered content
ob_end_clean();

// if not HTTP exception wrap it to one
if (!($exception instanceof HTTPException)) {
$exception = HTTPException::from($exception);
}
// get handler instance
$errorHandler = new (Configuration::ERROR_HANDLER_CLASS)();
// handle error and send response
$errorHandler->handleError($this, $exception)->send();
}

// if SQL debugging in configuration is allowed, display all SQL queries
if (Configuration::SHOW_SQL_QUERY) {
$queries = array_map(function ($q) {
$lines = explode("\n", $q);
$query = "Sent ";
foreach ($lines as $line) {
if (preg_match("/^Sent SQL: \[\d+\]/", $line)) {
$query = $line;
} else if (preg_match("/^Params: \d+/", $line)) {
break;
} else {
$query .= $line . "\n";
}
}
return '<pre>' . trim($query) . '</pre>';
}, Connection::getQueryLog());
echo implode(PHP_EOL . PHP_EOL, $queries);
}
}

/**
* @return Router
*/
public function getRouter(): Router
{
return $this->router;
}

/**
* @return Request
*/
public function getRequest(): Request
{
return $this->request;
}

/**
* @return IAuthenticator|null
*/
public function getAuth(): ?IAuthenticator
{
return $this->auth;
}

/**
* @return LinkGenerator
*/
public function getLinkGenerator(): LinkGenerator
{
return $this->linkGenerator;
}
}
90 changes: 90 additions & 0 deletions App/Auth/DummyAuthenticator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace App\Auth;

use App\Core\IAuthenticator;

/**
* Class DummyAuthenticator
* Basic implementation of user authentication
* @package App\Auth
*/
class DummyAuthenticator implements IAuthenticator
{
public const LOGIN = "admin";
public const PASSWORD_HASH = '$2y$10$GRA8D27bvZZw8b85CAwRee9NH5nj4CQA6PDFMc90pN9Wi4VAWq3yq'; // admin
public const USERNAME = "Admin";

/**
* DummyAuthenticator constructor
*/
public function __construct()
{
session_start();
}

/**
* Verify, if the user is in DB and has his password is correct
* @param $login
* @param $password
* @return bool
* @throws \Exception
*/
public function login($login, $password): bool
{
if ($login == self::LOGIN && password_verify($password, self::PASSWORD_HASH)) {
$_SESSION['user'] = self::USERNAME;
return true;
} else {
return false;
}
}

/**
* Logout the user
*/
public function logout(): void
{
if (isset($_SESSION["user"])) {
unset($_SESSION["user"]);
session_destroy();
}
}

/**
* Get the name of the logged-in user
* @return string
* @throws \Exception
*/
public function getLoggedUserName(): string
{
return isset($_SESSION['user']) ? $_SESSION['user'] : throw new \Exception("User not logged in");
}

/**
* Get the context of the logged-in user
* @return string
*/
public function getLoggedUserContext(): mixed
{
return null;
}

/**
* Return if the user is authenticated or not
* @return bool
*/
public function isLogged(): bool
{
return isset($_SESSION['user']) && $_SESSION['user'] != null;
}

/**
* Return the id of the logged-in user
* @return mixed
*/
public function getLoggedUserId(): mixed
{
return $_SESSION['user'];
}
}
54 changes: 54 additions & 0 deletions App/Config/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace App\Config;

use App\Auth\DummyAuthenticator;
use App\Core\ErrorHandler;

/**
* Class Configuration
* Main configuration for the application
* @package App\Config
*/
class Configuration
{
/**
* App name
*/
public const APP_NAME = 'Vaííčko MVC FW';
public const FW_VERSION = '2.2';

/**
* DB settings
*/
public const DB_HOST = 'db'; // see docker/docker-compose.yml
public const DB_NAME = 'vaiicko_db'; // see docker/.env
public const DB_USER = 'vaiicko_user'; // see docker/.env
public const DB_PASS = 'dtb456'; // see docker/.env

/**
* URL where main page logging is. If action needs login, user will be redirected to this url
*/
public const LOGIN_URL = '?c=auth&a=login';
/**
* Prefix of default view in App/Views dir. <ROOT_LAYOUT>.layout.view.php
*/
public const ROOT_LAYOUT = 'root';
/**
* Add all SQL queries after app output
*/
public const SHOW_SQL_QUERY = false;

/**
* Show detailed stacktrace using default exception handler. Should be used only for development.
*/
public const SHOW_EXCEPTION_DETAILS = true;
/**
* Class used as authenticator. Must implement IAuthenticator
*/
public const AUTH_CLASS = DummyAuthenticator::class;
/**
* Class used as error handler. Must implement IHandleError
*/
public const ERROR_HANDLER_CLASS = ErrorHandler::class;
}
33 changes: 33 additions & 0 deletions App/Controllers/AdminController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Controllers;

use App\Core\AControllerBase;
use App\Core\Responses\Response;

/**
* Class HomeController
* Example class of a controller
* @package App\Controllers
*/
class AdminController extends AControllerBase
{
/**
* Authorize controller actions
* @param $action
* @return bool
*/
public function authorize($action)
{
return $this->app->getAuth()->isLogged();
}

/**
* Example of an action (authorization needed)
* @return \App\Core\Responses\Response|\App\Core\Responses\ViewResponse
*/
public function index(): Response
{
return $this->html();
}
}
Loading

0 comments on commit 43a30d7

Please sign in to comment.