BG MVC sisteminde, core dizinindeki dosyalarda tanımlanmış toplam 8 adet temel sınıf kullanılmaktadır.
BG MVC temel sınıf tanımlamaları, core dizinindeki .php uzantılı dosyalarda yapılmaktadır.
core dizini altındaki Controller.php dosyası içinde tanımlanan Controller sınıfı, app/controllers dizini altındaki denetleyici dosyalarında yer alan tüm sınıfların türetildiği bir sınıftır.
C:\wamp\www\bgmvc\core\Controller.php
<?php
namespace Core;
use Core\{View, Config, Request};
class Controller {
private $_controller_name, $_action_name;
public $view, $request;
public function __construct($controller, $action) {
$this->_controller_name = $controller;
$this->_action_name = $action;
$view_path = strtolower($controller) . '/' .$action;
$this->view = new View($view_path);
$this->view->set_layout(Config::get('default_layout'));
$this->request = new Request();
$this->onConstruct();
}
public function onConstruct(){}
}
Controller sınıfı içinde 4 adet değişken oluşturulur:
app/controllers dizini altındaki denetleyici dosyalarından herhangi birinde yer alan sınıflardan birisinden bir nesne oluşturulduğunda, oluşturulan nesnenin tanımlandığı sınıfın türetildiği Controller sınıfının __construct() fonksiyonu otomatik olarak çağrılarak, $controller_name ve $action_name değerleri parametre olarak geçirilir.
Çağrılan __construct() fonksiyonu ile:
BG MVC projesinin core dizisi altında Config adlı bir sınıf tanımlanır.
config.php dosyasında tanımlı Config sınıfı veya .env dosyasında tanımlı ortam değişkenlerinden birini elde etmek için, Config sınıfında tanımlı get() fonksiyonu kullanılır. get() fonksiyonuna geçirilen parametre karşılığı olan değer, parametre değeri $_ENV değişken dizisinde mevcut ise oradan, değilse Config sınıfı içindeki $config dizisinden okunarak elde edilir.
C:\wamp\www\bgmvc\core\config.php
<?php
namespace Core;
class Config {
private static $config = [
'version' => '1.0.0',
'default_controller' => 'Home', // Ön tanımlı denetleyici
'default_layout' => 'default', // Ön tanımlı görünüm yapısı
'default_site_title' => 'BG MVC', // Ön tanımlı site başlığı
];
public static function get($key) {
if(array_key_exists($key, $_ENV)) return $_ENV[$key];
return array_key_exists($key, self::$config)? self::$config[$key] : NULL;
}
}
Ortam değişken dosyası (.env)
Ortam değişken dosyasında genellikle güvenlik sağlamak istediğimiz veriler yer alır.
C:\wamp\www\bgmvc\.env
root_dir="/bgmvc/"
db_host="127.0.0.1"
db_name="veritabani_adi"
db_user="kullanici_adi"
db_password="parola"
login_cookie_name="sgcdnfyrhfuwoqazpw"
exceptions="Exceptions"
main_slide=0
record_limit=4
Controller.php içindeki Controller sınıfından türetilen herhangi bir denetleyici sınıfı içindeki bir hareket fonksiyonundan, veritabanı işlemlerini gerçekleştirmek için, DB.php dosyasında tanımlı DB sınıfı oluşturulur.
Hareket fonksiyonunu, veritabanı işlemleri için, DB sınıfındaki getInstance() fonksiyonunu doğrudan çağırarak bir veritabanı nesnesi oluşturur:
$db = DB:get_instance();
Oluşturulan nesne yoluyla, DB sınıfındaki tüm değişken ve fonksiyonlara doğrudan veya dolaylı olarak erişim sağlar.
<?php
namespace Core;
use \PDO;
use \Exception;
use Core\{Config, H};
class DB {
protected $_dbh, $_results, $_last_insert_id, $_row_count = 0, $_fetch_type = PDO::FETCH_OBJ, $_class, $_error = false;
protected $_stmt;
protected static $_db;
public function __construct() {
$host = Config::get('db_host');
$name = Config::get('db_name');
$user = Config::get('db_user');
$pass = Config::get('db_password');
$options = [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_turkish_ci' // SET NAMES komutu PHP 5.3.6 öncesi için
];
try {
$this->_dbh = new PDO("mysql:host={$host};dbname={$name};charset=utf8mb4", $user, $pass, $options);
}
catch (Exception $e) {
throw new Exception($e->getMessage());
}
}
public static function get_instance() {
if(!self::$_db) {
self::$_db = new self();
}
return self::$_db;
}
public function execute($sql, $bind=[]) {
$this->_results = null;
$this->_last_insert_id = null;
$this->_error = false;
$this->_stmt = $this->_dbh->prepare($sql);
if(!$this->_stmt->execute($bind)) {
$this->_error = true;
}
else {
$this->_last_insert_id = $this->_dbh->lastInsertId();
}
return $this;
}
public function query($sql, $bind=[]) {
$this->execute($sql, $bind);
if(!$this->_error) {
$this->_row_count = $this->_stmt->rowCount();
if($this->_fetch_type === PDO::FETCH_CLASS) {
$this->_results = $this->_stmt->fetchAll($this->_fetch_type, $this->_class);
}
else {
$this->_results = $this->_stmt->fetchAll($this->_fetch_type);
}
}
return $this;
}
public function insert($table, $values) {
$fields = [];
$binds = [];
foreach($values as $key => $value) {
$fields[] = $key;
$binds[] = ":{$key}";
}
$field_str = implode('`, `', $fields);
$bind_str = implode(', ', $binds);
$sql = "INSERT INTO {$table} (`{$field_str}`) VALUES ({$bind_str})";
$this->execute($sql, $values);
return !$this->_error;
}
public function update($table, $values, $conditions) {
$binds = [];
$value_str = "";
foreach($values as $field => $value) {
$value_str .= ", `{$field}` = :{$field}";
$binds[$field] = $value;
}
$value_str = ltrim($value_str, ', ');
$sql = "UPDATE {$table} SET {$value_str}";
if(!empty($conditions)) {
$condition_str = " WHERE ";
foreach($conditions as $field => $value) {
$condition_str .= "`{$field}` = :cond{$field} AND ";
$binds['cond'.$field] = $value;
}
$condition_str = rtrim($condition_str, ' AND ');
$sql .= $condition_str;
}
$this->execute($sql, $binds);
return !$this->_error;
}
public function results() {
return $this->_results;
}
public function count() {
return $this->_row_count;
}
public function last_insert_id() {
return $this->_last_insert_id;
}
public function set_class($class) {
$this->_class = $class;
}
public function get_class() {
return $this->_class;
}
public function set_fetch_type($type) {
$this->_fetch_type = $type;
}
public function get_fetch_type() {
return $this->_fetch_type;
}
}
Controller.php içindeki Controller sınıfından türetilen herhangi bir denetleyici sınıfı içindeki bir hareket fonksiyonu, veritabanı işlemleri için, DB sınıfındaki get_instance() fonksiyonunu doğrudan çağırarak bir veritabanı nesnesi oluşturarak işlem yapar.
Controller.php içindeki Controller sınıfından türetilen herhangi bir denetleyici sınıfı içindeki bir hareket fonksiyonundan, veritabanı işlemlerini gerçekleştirmek için oluşturulan DB.php dosyasında tanımlı DB sınıfına erişim sağlayarak bu sınıfın fonksiyonlarını kullanmak için, Model.php dosyasında tanımlı Model sınıfı oluşturulur.
app/controllers dizininde tanımlı bir denetleyici hareket fonksiyonu içinden, kullanılacak veritabanı tablosu için Model sınıfından türetilerek oluşturulmuş olan bir sınıf arayüzü üzerinden Model sınıfı fonksiyonları doğrudan çağrılarak DB sınıfı fonksiyonlarına erişim sağlanır.
<?php
namespace Core;
use \PDO;
use Core\{DB, Router};
class Model {
protected static $table = "";
protected static $columns = false;
protected $_validation_passed = true, $_errors = [], $_skip_update = [];
protected static function get_db($set_fetch_class = false) {
$db = DB::get_instance();
if($set_fetch_class) {
$db->set_class(get_called_class());
$db->set_fetch_type(PDO::FETCH_CLASS);
}
return $db;
}
public static function insert($values) {
$db = static::get_db();
return $db->insert(static::$table, $values);
}
public static function update($values, $conditions) {
$db = static::get_db();
return $db->update(static::$table, $values, $conditions);
}
public function delete() {
$db = static::get_db();
$table = static::$table;
$params = [
'conditions' => "id = :id",
'bind' => ['id' => $this->id]
];
list('sql' => $conds, 'bind' => $bind) = self::query_param_builder($params);
$sql = "DELETE FROM {$table} {$conds}";
return $db->execute($sql, $bind);
}
public static function find($params = []) {
$db = static::get_db(true);
list('sql' => $sql, 'bind' => $bind) = self::select_builder($params);
return $db->query($sql, $bind)->results();
}
public static function find_first($params = []) {
$db = static::get_db(true);
list('sql' => $sql, 'bind' => $bind) = self::select_builder($params);
$results = $db->query($sql, $bind)->results();
return isset($results[0])? $results[0] : false;
}
public static function find_by_id($id) {
return static::find_first([
'conditions' => "id = :id",
'bind' => ['id' => $id]
]);
}
public static function find_total($params = []) {
unset($params['limit']);
unset($params['offset']);
$table = static::$table;
$sql = "SELECT COUNT(*) AS total FROM {$table}";
list('sql' => $conds, 'bind' => $bind) = self::query_param_builder($params);
$sql .= $conds;
$db = static::get_db();
$results = $db->query($sql, $bind);
$total = sizeof($results->results()) > 0 ? $results->results()[0]->total : 0;
return $total;
}
public function save() {
$save = false;
$this->before_save();
if($this->_validation_passed) {
$db = static::get_db();
$values = $this->get_values_for_save();
if($this->is_new(()) {
$save = $db->insert(static::$table, $values);
if($save) {
$this->id = $db->last_insert_id();
}
} else {
$save = $db->update(static::$table,$values, ['id' => $this->id]);
}
}
return $save;
}
public function is_new(() {
return empty($this->id);
}
public static function select_builder($params = []) {
$columns = array_key_exists('columns', $params)? $params['columns'] : "*";
$table = static::$table;
$sql = "SELECT {$columns} FROM {$table}";
list('sql' => $conds, 'bind' => $bind) = self::query_param_builder($params);
$sql .= $conds;
return ['sql' => $sql, 'bind' => $bind];
}
public static function query_param_builder($params = []) {
$sql = "";
$bind = array_key_exists('bind', $params)? $params['bind'] : [];
// joins
// [['table2', 'table1.id = table2.key', 'tableAlias', 'LEFT' ]]
if(array_key_exists('joins', $params)) {
$joins = $params['joins'];
foreach($joins as $join) {
$join_table = $join[0];
$join_on = $join[1];
$join_alias = isset($join[2])? $join[2] : "";
$join_type = isset($join[3])? "{$join[3]} JOIN" : "JOIN";
$sql .= " {$join_type} {$join_table} {$join_alias} ON {$join_on}";
}
}
// where
if(array_key_exists('conditions', $params)) {
$conds = $params['conditions'];
$sql .= " WHERE {$conds}";
}
// group
if(array_key_exists('group', $params)) {
$group = $params['group'];
$sql .= " GROUP BY {$group}";
}
// order
if(array_key_exists('order', $params)) {
$order = $params['order'];
$sql .= " ORDER BY {$order}";
}
// limit
if(array_key_exists('limit', $params)) {
$limit = $params['limit'];
$sql .= " LIMIT {$limit}";
}
// offset
if(array_key_exists('offset', $params)) {
$offset = $params['offset'];
$sql .= " OFFSET {$offset}";
}
return ['sql' => $sql, 'bind' => $bind];
}
public function get_values_for_save() {
$columns = static::get_columns();
$values = [];
foreach($columns as $column) {
if(!in_array($column, $this->_skip_update)) {
$values[$column] = $this->{$column};
}
}
return $values;
}
public static function get_columns() {
if(!static::$columns) {
$db = static::get_db();
$table = static::$table;
$sql = "SHOW COLUMNS FROM {$table}";
$results = $db->query($sql)->results();
$columns = [];
foreach($results as $column) {
$columns[] = $column->Field;
}
static::$columns = $columns;
}
return static::$columns;
}
public function run_validation($validator) {
$validates = $validator->run_validation();
if(!$validates) {
$this->_validation_passed = false;
$this->_errors[$validator->field] = $validator->msg;
}
}
public function get_errors() {
return $this->_errors;
}
public function set_error($name, $value) {
$this->_errors[$name] = $value;
$this->_validation_passed = false;
}
public function time_stamps() {
$dt = new \DateTime("now", new \DateTimeZone("UTC"));
$now = $dt->format('Y-m-d H:i:s');
$this->updated_at = $now;
if($this->is_new(()) {
$this->created_at = $now;
}
}
public static function merge_with_pagination($params, $pageno, $total) {
if(isset($_POST['records_limit'])) {
$_SESSION['records_limit'] = $_POST['records_limit'];
}
$limit = isset($_SESSION['records_limit']) ? $_SESSION['records_limit'] : (int) Config::get('record_limit');
if((int)$pageno>ceil($total/$limit)) {
Router::redirect('exceptions/index/nopage');
}
$page = $pageno!='' ? $pageno : 1;
$pagination_start = ($page - 1) * $limit;
$params['limit'] = $limit;
$params['offset'] = $pagination_start;
return [$params, $page];
}
public function before_save(){}
}
Controller.php içindeki Controller sınıfından türetilen herhangi bir denetleyici sınıfı içindeki bir hareket fonksiyonundan, yapılan görüntü işlemlerini gerçekleştirmek için, View.php dosyasında tanımlı View sınıfı oluşturulur.
<?php
namespace Core;
use Core\{Config, Router};
class View {
public $articles, $total, $heading;
public $errors, $user, $header, $users, $article;
public $msg, $msg_txt, $limit, $page, $url;
private $_site_title = '', $_content = [], $_current_content, $_buffer, $_layout;
private $_default_view_path;
public function __construct($path = '') {
$this->_default_view_path = $path;
$this->_site_title = Config::get('default_site_title');
}
public function set_layout($layout) {
$this->_layout = $layout;
}
public function set_site_title($title) {
$this->_site_title = $title;
}
public function get_site_title() {
return $this->_site_title;
}
public function render($path = '') {
if(empty($path)) {
$path = $this->_default_view_path;
}
$layout_path = FROOT . DS . 'app' . DS . 'views' . DS . 'layouts' . DS . $this->_layout . '.php';
$full_path = FROOT . DS . 'app' . DS . 'views' . DS . $path . '.php';
if(!file_exists($full_path)) {
Router::redirect('exceptions/index/noview');
}
if(!file_exists($layout_path)) {
Router::redirect('exceptions/index/notemplate');
}
include($full_path);
include($layout_path);
}
public function start($key) {
if(empty($key)) {
Router::redirect('exceptions/index/nokey');
}
$this->_buffer = $key;
ob_start();
}
public function end() {
if(empty($this->_buffer)) {
Router::redirect('exceptions/index/nostart');
}
$this->_content[$this->_buffer] = ob_get_clean();
$this->_buffer = null;
}
public function content($key) {
if(array_key_exists($key, $this->_content)) {
echo $this->_content[$key];
}
else {
echo '';
}
}
public function inc($path) {
$full_path = FROOT . DS . 'app' . DS . 'views' . DS . $path . '.php';
if(file_exists($full_path)) {
include($full_path);
}
}
}
Görüntü sınıfı kullanımı
1. Controller.php içindeki Controller sınıfından türetilen herhangi bir denetleyici sınıfı içindeki bir hareket fonksiyonundan, Controller sınıfı içinde tanmlı view değişkeni yoluyla, View.php dosyasında tanımlı View sınıfı içindeki render() fonksiyonu çağrılır.
$this->view->render('home/index');
2. render() fonksiyonu, kendisine geçirilen parametre değerine (home/index) karşılık gelen dosya ile şablon dosyası mevcut ise, sırayla görünüme dahil eder:
Proje ana dizinde bulunan index.php dosyasına yönlendirilen tüm akışlar, gerekli işlemler yapıldıktan sonra, URL değerleri parameter olarak kullanılarak, Router.php dosyasındaki Router sınıfı içinde yer alan route($url) yönlendirici fonksiyonuna geçirilir.
Ana dizin altındaki core dizini altında Router.php adlı bir dosya oluşturulur:
C:\wamp\www\bgmvc\core\Router.php
<?php
namespace Core;
use Core\Session;
use App\Models\Users;
class Router {
public static function route($url) {
$error = false;
// $url[0] = 'Denetleyici'
$controller = !empty($url[0]) ? ucwords($url[0]) : Config::get('default_controller'); // $controller = 'Home'
$controller_name = $controller; // $controller_name = 'Home'
$controller = '\App\Controllers\\' . $controller . 'Controller'; // $controller = '\App\Controllers\HomeController'
// URL satırında sadece denetleyici adı girilmişse ve bu denetleyiciye ait index.php dosyası varsa,
// index değerini action olarak URL'ye eklemek için (İçinde index.php olmayan denetleyici dizinlerine girişi bloke etmek için)
$index_exist = file_exists(FROOT . DS . 'app' . DS . 'views' . DS . lcfirst($controller_name) . DS . 'index.php');
// $url içinde denetleyici ve hareket değeri mevcutsa, denetleyici değerini siler, hareket değeri dizi başına gelir.
array_shift($url); // $url[0] = 'Hareket'
// Seçilen yol içinde action var ise atanır, yoksa $controller_name'e ait index.php dosyası varsa 'index' atanır.
// Böylece diğer dizinler için mevcut bir index.php yoksa $action boş kalır ve method_exists() koşulunu geçemez.
$action = !empty($url[0]) ? $url[0] : ($index_exist ? 'index' : ''); // $action = 'index'
$action_name = $action; // $action_name = 'index'
$action .= "Action"; // $action = 'indexAction'
// $url içinde hareket değeri mevcutsa, hareket değerini siler, parametre değeri dizi başına gelir.
array_shift($url); // $url[0] = 'Parametre 1', $url[1] = 'Parametre 2', ...
// Denetleyici sınıfı veya hareket metodu mevcut değilse, $url dizisine sayfanın mevcut olmadığını gösteren bir değer atar.
if(!class_exists($controller) || !method_exists($controller, $action)) {
$url = ["nopage"];
$error = true;
}
else {
// acl kontrolü (acl.json dosyası ile menüde gösterilmeyen sayfalara erişimi engeller)
// Menüde gösterilen sayfalara erişimi engellemek için ayrıca işlem gerekir (if($current_user->acl=='admin')).
$grant_access = self::has_access($controller_name, $action_name);
// Kullanıcının giriş izni yoksa, $url dizisine giriş izni olmadığını gösteren bir değer atar.
if(!$grant_access) {
$url = ["noaccess"];
$error = true;
}
}
// Sınıf veya metod olmamasından (nopage) veya giriş izni olmamasından (noaccess) kaynaklı hata varsa,
// sayfayı hata gösterimine yönlendirecek şekilde, denetleyici ve hareket adını değiştirir.
if($error) {
$controller = str_replace($controller_name, Config::get('exceptions'), $controller);
$controller_name = Config::get('exceptions'); // $controller_name = 'Exceptions'
$action_name = 'index'; // $action_name = 'index'
$action = $action_name . 'Action'; // $action = 'indexAction'
}
// HomeController sınıfı cinsinden bir nesne oluşturur. Bu işlemi yaparken, HomeController sınıfının türetildiği Controller
// sınıfının __construct() fonksiyonunu otomatik olarak çağırarak, $controller_name ve $action_name değerlerini geçirir.
// $controller = '\App\Controllers\HomeController', $controller_name = 'Home', $action_name = 'index'
$controller_class = new $controller($controller_name, $action_name);
// HomeController sınıfındaki $action fonksiyonunu (indexAction) $url parametreleri ile çağırma
call_user_func_array([$controller_class, $action], $url); // $action = 'indexAction', $url = params
}
public static function redirect($location) {
if(!headers_sent()) {
header('Location: ' . ROOT . $location);
}
else {
echo '<script type="text/javascript">';
echo 'window.location.href = "'. ROOT . $location .'"';
echo '</script>';
echo '<nosript>';
echo '<meta http-equiv="refresh" content="0;url=' . ROOT . $location . '" />';
echo '</nosript>';
}
exit();
}
public static function perm_redirect($perm, $redirect, $msg = "Bu sayfaya giriş yapamazsınız.") {
$user = Users::get_current_user();
$allowed = $user && $user->has_permission($perm);
if(!$allowed) {
Session::msg($msg);
self::redirect($redirect);
}
}
public static function get_menu($menu) {
$menu_array = [];
$menu_file = file_get_contents(FROOT . DS . 'app/views/inc' . DS . $menu . '.json');
$acl = json_decode($menu_file, true);
foreach($acl as $key => $val) {
if(is_array($val)) {
$sub = [];
foreach($val as $k => $v) {
if(substr($k,0,9) == 'separator' && !empty($sub)) {
$sub[$k] = '';
continue;
}
else if($final_val = self::get_link($v)) {
$sub[$k] = $final_val;
}
}
if(!empty($sub)) {
$menu_array[$key] = $sub;
}
}
else {
if($final_val = self::get_link($val)) {
$menu_array[$key] = $final_val;
}
}
}
return $menu_array;
}
private static function get_link($val) {
// Harici bağlantı ise
if(preg_match('/https?:\/\//', $val) == 1) {
return $val;
}
else {
$uAry = explode('/', $val);
$controller_name = ucwords($uAry[0]);
$action_name = (isset($uAry[1]))? $uAry[1] : '';
if(self::has_access($controller_name, $action_name)) {
return $val;
}
return false;
}
}
public static function has_access($controller_name, $action_name='index') {
$acl_file = file_get_contents(FROOT . DS . 'app/views/inc' . DS . 'acl.json');
$acl = json_decode($acl_file, true);
$current_user_acls = ["Guest"];
$grant_access = false;
if(Session::exists('logged_in_user')) {
$current_user_acls[] = "LoggedIn";
$current_user_acls[] = ucwords(Users::get_current_user()->acl); // Veritabanındaki users tablosunda acl değeri tek ise
}
foreach($current_user_acls as $level) { // 'Guest', 'LoggedIn' ve 'Admin'
if(array_key_exists($level, $acl) && array_key_exists($controller_name, $acl[$level])) {
if(in_array($action_name, $acl[$level][$controller_name]) || in_array("*", $acl[$level][$controller_name])) {
$grant_access = true;
break;
}
}
}
// Girişi bloke edilen menü seçenekleri
foreach($current_user_acls as $level) {
$denied = $acl[$level]['denied'];
if(!empty($denied) && array_key_exists($controller_name, $denied) && in_array($action_name, $denied[$controller_name])) {
$grant_access = false;
break;
}
}
return $grant_access;
}
}
Router.php dosyasında sırayla aşağıdaki işlemler gerçekleştirilir:
C:\wamp\www\bgmvc\core\Request.php
<?php
namespace Core;
class Request {
public function isPost() {
return $this->get_request_method() === 'POST';
}
public function isPut(){
return $this->get_request_method() === 'PUT';
}
public function isGet(){
return $this->get_request_method() === 'GET';
}
public function isDelete(){
return $this->get_request_method() === 'DELETE';
}
public function isPatch(){
return $this->get_request_method() === 'PATCH';
}
public function get_request_method(){
return strtoupper($_SERVER['REQUEST_METHOD']);
}
public function get($input = false) {
if(!$input) {
$data = [];
foreach($_REQUEST as $field => $value) {
$data[$field] = self::sanitize($value);
}
return $data;
}
return array_key_exists($input, $_REQUEST) ? self::sanitize($_REQUEST[$input]) : false;
}
public static function sanitize($dirty) {
return htmlentities(trim($dirty), ENT_QUOTES, "UTF-8");
}
}
C:\wamp\www\bgmvc\core\Session.php
<?php
namespace Core;
use Core\{Request, H};
class Session {
public static function exists($name) {
return isset($_SESSION[$name]);
}
public static function set($name, $value) {
$_SESSION[$name] = $value;
}
public static function get($name) {
if(self::exists($name) && !empty($_SESSION[$name])) {
return $_SESSION[$name];
}
return false;
}
public static function delete($name) {
unset($_SESSION[$name]);
}
public static function create_csrf_token() {
$token = md5('csrf'.time());
self::set('csrfToken', $token);
return $token;
}
public static function csrf_check() {
$request = new Request();
$check = $request->get('csrfToken');
if(self::exists('csrfToken') && self::get('csrfToken') == $check){
return true;
}
Router::redirect('exceptions/index/badtoken'); // Router::redirect('home/badToken');
}
public static function msg($msg, $type = 'danger') {
$alerts = self::exists('session_alerts')? self::get('session_alerts') : [];
$alerts[$type][] = $msg;
self::set('session_alerts', $alerts);
}
public static function display_session_alerts() {
$alerts = self::exists('session_alerts')? self::get('session_alerts') : [];
$html = "";
foreach($alerts as $type => $msgs) {
foreach($msgs as $msg) {
$html .= "<div class='alert alert-{$type} alert-dismissible m-3' role='alert'><div>{$msg}</div><button type='button' class='btn-close' data-bs-dismiss='alert' aria-label='Close'></button></div>";
}
}
self::delete('session_alerts');
return $html;
}
}
C:\wamp\www\bgmvc\core\Cookie.php
<?php
namespace Core;
class Cookie {
public static function get($name) {
if(self::exists($name)) {
return $_COOKIE[$name];
}
return false;
}
public static function set($name, $value, $expiry) {
if(setCookie($name, $value, time()+$expiry, '/')){
return true;
}
return false;
}
public static function delete($name) {
return self::set($name, '', -1);
}
public static function exists($name) {
return isset($_COOKIE[$name]);
}
}
C:\wamp\www\bgmvc\core\H.php
<?php
namespace Core;
class H {
public static function remove_root($url) {
if(ROOT != '/') { // En soldaki '/bgmvc/' (Lokal sunucu) veya '/' (Uzak sunucu) değerini kaldırma
$url = str_replace(ROOT, '', $url);
}
else { // '/' değerini kaldırma (Canlı sunucu) $url = '/' -> $url = ''
$url = ltrim($url, '/');
}
// $url değerinin en sağında yer alabilecek id=21&md=34 gibi değerleri silmek için
$url = preg_replace('/(\?.+)/', '', $url);
return $url;
}
public static function get_action() {
$url = self::remove_root($_SERVER['REQUEST_URI']);
$url = explode ('/', $url);
$link = ((isset($url[0]) && $url[0]!='') ? $url[0] : 'home') . '/' . (isset($url[1]) ? $url[1] : 'index') . (isset($url[2]) && ($url[1]=='author' || $url[1]=='category') ? ('/' . $url[2]) : '');
return $link;
}
public static function dnd($data=[], $die = true){
echo "<pre>";
var_dump($data);
echo "</pre>";
if($die) {
die;
}
}
public static function is_current_page($page) {
global $current_page;
if(!empty($page) && strpos($page, ':id') > -1) {
$page = str_replace(":id", "", $page);
return strpos($current_page, $page) > -1;
}
return $page == $current_page;
}
public static function active_class($page, $class = '') {
$active = self::is_current_page($page);
$class = $active ? $class . " active" : $class;
return $class;
}
public static function nav_item($link, $label, $is_dropdown_item = false) {
$active = self::is_current_page($link);
$class = self::active_class($link, 'nav-item');
$link_class = $is_dropdown_item ? 'dropdown-item' : 'nav-link';
$link_class .= $active ? " active" : "";
$link = ROOT . $link;
$html = "<li>";
$html .= "<a class=\"{$link_class}\" href=\"{$link}\" >{$label}</a>";
$html .= "</li>";
return $html;
}
}
C:\wamp\www\bgmvc\core\FH.php
<?php
namespace Core;
class FH {
public static function input_block($label, $id, $value, $input_attrs =[], $wrapper_attrs = [], $errors = []) {
$wrapper_str = self::process_attrs($wrapper_attrs);
$input_attrs = self::append_errors($id, $input_attrs, $errors);
$input_attrs = self::process_attrs($input_attrs);
$error_msg = array_key_exists($id, $errors)? $errors[$id] : "";
$html = "<div {$wrapper_str}>";
$html .= "<label for='{$id}' class='form-label small'>{$label}</label>";
$html .= "<input id='{$id}' name='{$id}' value='{$value}' {$input_attrs} />";
$html .= "<div class='invalid-feedback'>{$error_msg}</div></div>";
return $html;
}
public static function select_block($label, $id, $value, $options, $input_attrs=[], $wrapper_attrs=[], $errors=[]) {
$input_attrs = self::append_errors($id, $input_attrs, $errors);
$input_attrs = self::process_attrs($input_attrs);
$wrapper_str = self::process_attrs($wrapper_attrs);
$error_msg = array_key_exists($id, $errors)? $errors[$id] : "";
$html = "<div {$wrapper_str}>";
$html .= "<label for='{$id}' class='form-label small'>{$label}</label>";
$html .= "<select id='{$id}' name='{$id}' {$input_attrs}>";
foreach($options as $val => $display) {
$selected = $val == $value? ' selected ' : "";
$html .= "<option value='{$val}'{$selected}>{$display}</option>";
}
$html .= "</select>";
$html .= "<div class='invalid-feedback'>{$error_msg}</div></div>";
return $html;
}
public static function check($label, $id, $checked = '', $input_attrs=[], $wrapper_attrs=[], $errors=[]) {
$input_attrs = self::append_errors($id, $input_attrs, $errors);
$wrapper_str = self::process_attrs($wrapper_attrs);
$input_str = self::process_attrs($input_attrs);
$checked_str = $checked == 'on'? "checked" : "";
$html = "<div {$wrapper_str}>";
$html .= "<input type=\"checkbox\" id=\"{$id}\" name=\"{$id}\" {$input_str} {$checked_str}>";
$html .= "<label class=\"form-check-label\" for=\"{$id}\">{$label}</label></div>";
return $html;
}
public static function text_area($label, $id, $value, $input_attrs =[], $wrapper_attrs = [], $errors = []) {
$wrapper_str = self::process_attrs($wrapper_attrs);
$input_attrs = self::append_errors($id, $input_attrs, $errors);
$input_attrs = self::process_attrs($input_attrs);
$error_msg = array_key_exists($id, $errors)? $errors[$id] : "";
$html = "<div {$wrapper_str}>";
$html .= "<label for='{$id}' class='form-label small'>{$label}</label>";
$html .= "<textarea id='{$id}' name='{$id}' value='{$value}' {$input_attrs}>{$value}</textarea>";
$html .= "<div class='invalid-feedback'>{$error_msg}</div></div>";
return $html;
}
public static function append_errors($key, $input_attrs, $errors) {
if(array_key_exists($key, $errors)) {
if(array_key_exists('class', $input_attrs)) {
$input_attrs['class'] .= ' is-invalid';
}
else {
$input_attrs['class'] = 'is-invalid';
}
}
return $input_attrs;
}
public static function process_attrs($attrs) {
$html = "";
foreach($attrs as $key => $value) {
$html .= " {$key}='{$value}'";
}
return $html;
}
public static function csrf_field(){
$token = Session::create_csrf_token();
$html = "<input type='hidden' value='{$token}' name='csrfToken' />";
return $html;
}
}