-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 831487c
Showing
19 changed files
with
1,012 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
/** | ||
* User: TheCodeholic | ||
* Date: 7/7/2020 | ||
* Time: 9:57 AM | ||
*/ | ||
|
||
namespace app\core; | ||
|
||
use app\core\db\Database; | ||
|
||
/** | ||
* Class Application | ||
* | ||
* @author Zura Sekhniashvili <[email protected]> | ||
* @package app | ||
*/ | ||
class Application | ||
{ | ||
public static Application $app; | ||
public static string $ROOT_DIR; | ||
public string $userClass; | ||
public string $layout = 'main'; | ||
public Router $router; | ||
public Request $request; | ||
public Response $response; | ||
public ?Controller $controller = null; | ||
public Database $db; | ||
public Session $session; | ||
public View $view; | ||
public ?UserModel $user; | ||
|
||
public function __construct($rootDir, $config) | ||
{ | ||
$this->user = null; | ||
$this->userClass = $config['userClass']; | ||
self::$ROOT_DIR = $rootDir; | ||
self::$app = $this; | ||
$this->request = new Request(); | ||
$this->response = new Response(); | ||
$this->router = new Router($this->request, $this->response); | ||
$this->db = new Database($config['db']); | ||
$this->session = new Session(); | ||
$this->view = new View(); | ||
|
||
$userId = Application::$app->session->get('user'); | ||
if ($userId) { | ||
$key = $this->userClass::primaryKey(); | ||
$this->user = $this->userClass::findOne([$key => $userId]); | ||
} | ||
} | ||
|
||
public static function isGuest() | ||
{ | ||
return !self::$app->user; | ||
} | ||
|
||
public function login(UserModel $user) | ||
{ | ||
$this->user = $user; | ||
$primaryKey = $user->primaryKey(); | ||
$value = $user->{$primaryKey}; | ||
Application::$app->session->set('user', $value); | ||
|
||
return true; | ||
} | ||
|
||
public function logout() | ||
{ | ||
$this->user = null; | ||
self::$app->session->remove('user'); | ||
} | ||
|
||
public function run() | ||
{ | ||
try { | ||
echo $this->router->resolve(); | ||
} catch (\Exception $e) { | ||
echo $this->router->renderView('_error', [ | ||
'exception' => $e, | ||
]); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
/** | ||
* User: TheCodeholic | ||
* Date: 7/8/2020 | ||
* Time: 8:43 AM | ||
*/ | ||
|
||
namespace app\core; | ||
|
||
use app\core\middlewares\BaseMiddleware; | ||
/** | ||
* Class Controller | ||
* | ||
* @author Zura Sekhniashvili <[email protected]> | ||
* @package app\core | ||
*/ | ||
class Controller | ||
{ | ||
public string $layout = 'main'; | ||
public string $action = ''; | ||
|
||
/** | ||
* @var \app\core\BaseMiddleware[] | ||
*/ | ||
protected array $middlewares = []; | ||
|
||
public function setLayout($layout): void | ||
{ | ||
$this->layout = $layout; | ||
} | ||
|
||
public function render($view, $params = []): string | ||
{ | ||
return Application::$app->router->renderView($view, $params); | ||
} | ||
|
||
public function registerMiddleware(BaseMiddleware $middleware) | ||
{ | ||
$this->middlewares[] = $middleware; | ||
} | ||
|
||
/** | ||
* @return \app\core\middlewares\BaseMiddleware[] | ||
*/ | ||
public function getMiddlewares(): array | ||
{ | ||
return $this->middlewares; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<?php | ||
/** | ||
* User: TheCodeholic | ||
* Date: 7/8/2020 | ||
* Time: 9:16 AM | ||
*/ | ||
|
||
namespace app\core; | ||
|
||
|
||
/** | ||
* Class Model | ||
* | ||
* @author Zura Sekhniashvili <[email protected]> | ||
* @package app\core | ||
*/ | ||
class Model | ||
{ | ||
const RULE_REQUIRED = 'required'; | ||
const RULE_EMAIL = 'email'; | ||
const RULE_MIN = 'min'; | ||
const RULE_MAX = 'max'; | ||
const RULE_MATCH = 'match'; | ||
const RULE_UNIQUE = 'unique'; | ||
|
||
public array $errors = []; | ||
|
||
public function loadData($data) | ||
{ | ||
foreach ($data as $key => $value) { | ||
if (property_exists($this, $key)) { | ||
$this->{$key} = $value; | ||
} | ||
} | ||
} | ||
|
||
public function attributes() | ||
{ | ||
return []; | ||
} | ||
|
||
public function labels() | ||
{ | ||
return []; | ||
} | ||
|
||
public function getLabel($attribute) | ||
{ | ||
return $this->labels()[$attribute] ?? $attribute; | ||
} | ||
|
||
public function rules() | ||
{ | ||
return []; | ||
} | ||
|
||
public function validate() | ||
{ | ||
foreach ($this->rules() as $attribute => $rules) { | ||
$value = $this->{$attribute}; | ||
foreach ($rules as $rule) { | ||
$ruleName = $rule; | ||
if (!is_string($rule)) { | ||
$ruleName = $rule[0]; | ||
} | ||
if ($ruleName === self::RULE_REQUIRED && !$value) { | ||
$this->addErrorByRule($attribute, self::RULE_REQUIRED); | ||
} | ||
if ($ruleName === self::RULE_EMAIL && !filter_var($value, FILTER_VALIDATE_EMAIL)) { | ||
$this->addErrorByRule($attribute, self::RULE_EMAIL); | ||
} | ||
if ($ruleName === self::RULE_MIN && strlen($value) < $rule['min']) { | ||
$this->addErrorByRule($attribute, self::RULE_MIN, ['min' => $rule['min']]); | ||
} | ||
if ($ruleName === self::RULE_MAX && strlen($value) > $rule['max']) { | ||
$this->addErrorByRule($attribute, self::RULE_MAX); | ||
} | ||
if ($ruleName === self::RULE_MATCH && $value !== $this->{$rule['match']}) { | ||
$this->addErrorByRule($attribute, self::RULE_MATCH, ['match' => $rule['match']]); | ||
} | ||
if ($ruleName === self::RULE_UNIQUE) { | ||
$className = $rule['class']; | ||
$uniqueAttr = $rule['attribute'] ?? $attribute; | ||
$tableName = $className::tableName(); | ||
$db = Application::$app->db; | ||
$statement = $db->prepare("SELECT * FROM $tableName WHERE $uniqueAttr = :$uniqueAttr"); | ||
$statement->bindValue(":$uniqueAttr", $value); | ||
$statement->execute(); | ||
$record = $statement->fetchObject(); | ||
if ($record) { | ||
$this->addErrorByRule($attribute, self::RULE_UNIQUE); | ||
} | ||
} | ||
} | ||
} | ||
return empty($this->errors); | ||
} | ||
|
||
public function errorMessages() | ||
{ | ||
return [ | ||
self::RULE_REQUIRED => 'This field is required', | ||
self::RULE_EMAIL => 'This field must be valid email address', | ||
self::RULE_MIN => 'Min length of this field must be {min}', | ||
self::RULE_MAX => 'Max length of this field must be {max}', | ||
self::RULE_MATCH => 'This field must be the same as {match}', | ||
self::RULE_UNIQUE => 'Record with with this {field} already exists', | ||
]; | ||
} | ||
|
||
public function errorMessage($rule) | ||
{ | ||
return $this->errorMessages()[$rule]; | ||
} | ||
|
||
protected function addErrorByRule(string $attribute, string $rule, $params = []) | ||
{ | ||
$params['field'] ??= $attribute; | ||
$errorMessage = $this->errorMessage($rule); | ||
foreach ($params as $key => $value) { | ||
$errorMessage = str_replace("{{$key}}", $value, $errorMessage); | ||
} | ||
$this->errors[$attribute][] = $errorMessage; | ||
} | ||
|
||
public function addError(string $attribute, string $message) | ||
{ | ||
$this->errors[$attribute][] = $message; | ||
} | ||
|
||
public function hasError($attribute) | ||
{ | ||
return $this->errors[$attribute] ?? false; | ||
} | ||
|
||
public function getFirstError($attribute) | ||
{ | ||
$errors = $this->errors[$attribute] ?? []; | ||
return $errors[0] ?? ''; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
/** | ||
* User: TheCodeholic | ||
* Date: 7/7/2020 | ||
* Time: 10:23 AM | ||
*/ | ||
|
||
namespace app\core; | ||
|
||
|
||
/** | ||
* Class Request | ||
* | ||
* @author Zura Sekhniashvili <[email protected]> | ||
* @package thecodeholic\mvc | ||
*/ | ||
class Request | ||
{ | ||
public function getMethod() | ||
{ | ||
return strtolower($_SERVER['REQUEST_METHOD']); | ||
} | ||
|
||
public function getUrl() | ||
{ | ||
$path = $_SERVER['REQUEST_URI']; | ||
$position = strpos($path, '?'); | ||
if ($position !== false) { | ||
$path = substr($path, 0, $position); | ||
} | ||
return $path; | ||
} | ||
|
||
public function isGet() | ||
{ | ||
return $this->getMethod() === 'get'; | ||
} | ||
|
||
public function isPost() | ||
{ | ||
return $this->getMethod() === 'post'; | ||
} | ||
|
||
public function getBody() | ||
{ | ||
$data = []; | ||
if ($this->isGet()) { | ||
foreach ($_GET as $key => $value) { | ||
$data[$key] = filter_input(INPUT_GET, $key, FILTER_SANITIZE_SPECIAL_CHARS); | ||
} | ||
} | ||
if ($this->isPost()) { | ||
foreach ($_POST as $key => $value) { | ||
$data[$key] = filter_input(INPUT_POST, $key, FILTER_SANITIZE_SPECIAL_CHARS); | ||
} | ||
} | ||
return $data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
/** | ||
* User: TheCodeholic | ||
* Date: 7/7/2020 | ||
* Time: 10:53 AM | ||
*/ | ||
|
||
namespace app\core; | ||
|
||
|
||
/** | ||
* Class Response | ||
* | ||
* @author Zura Sekhniashvili <[email protected]> | ||
* @package app\core | ||
*/ | ||
class Response | ||
{ | ||
public function statusCode(int $code) | ||
{ | ||
http_response_code($code); | ||
} | ||
|
||
public function redirect($url) | ||
{ | ||
header("Location: $url"); | ||
} | ||
} |
Oops, something went wrong.