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:
class Controller {
private $_controller_name, $_action_name;
public $view, $request;
public function __construct($controller, $action) {
$this->_controller_name = $controller;
$this->_action_name = $action;
$viewPath = strtolower($controller) . '/' .$action;
$this->view = new View($viewPath);
$this->view->setLayout(Config::get('default_layout'));
$this->request = new Request();
$this->onConstruct();
}
public function onConstruct(){}
}
Yerel sunucuda, siteye ilk giriş durumunda değişkenlerin aldığı değerler aşağıda gösterilmektedir:
Yerel sunucuda, siteye ilk giriş durumunda değişkenlerin aldığı değerler aşağıda gösterilmektedir:
http://localhost/bgmvc/ (Siteye ilk giriş)
1. $url değeri: array (size=1) 0 => string '' (length=0) $controller_name: Home $controller: \App\Controllers\HomeController 2. $url değeri: array (size=0) empty $action_name: index $action: indexAction 3. $url değeri: array (size=0) empty $controller: \App\Controllers\HomeController $action: indexAction $controller_name: Home $action_name: index $grant_access: İzin var $controller_class değeri: object(App\Controllers\HomeController)[46] private '_controller_name' (Core\Controller) => string 'Home' (length=4) private '_action_name' (Core\Controller) => string 'index' (length=5) public 'view' => object(Core\View)[43] public 'articles' => null public 'total' => null public 'heading' => null public 'errors' => null public 'user' => null public 'header' => null public 'users' => null public 'article' => null public 'msg' => null public 'limit' => null public 'page' => null public 'url' => null private '_site_title' => string 'BG MVC' (length=6) private '_content' => array (size=0) empty private '_current_content' => null private '_buffer' => null private '_layout' => string 'default' (length=7) private '_default_view_path' => string 'home/index' (length=10) public 'request' => object(Core\Request)[38]
Yerel sunucuda, siteye denetleyici, hareket ve bir parametre ile giriş durumunda değişkenlerin aldığı değerler aşağıda gösterilmektedir:
http://localhost/bgmvc/home/details/5 (Denetleyici, hareket ve bir parametre)
1. $url değeri: array (size=3) 0 => string 'home' (length=4) 1 => string 'details' (length=7) 2 => string '5' (length=1) $controller_name: Home $controller: \App\Controllers\HomeController 2. $url değeri: array (size=2) 0 => string 'details' (length=7) 1 => string '5' (length=1) $action_name: details $action: detailsAction 3. $url değeri: array (size=1) 0 => string '5' (length=1) $controller: \App\Controllers\HomeController $action: detailsAction $controller_name: Home $action_name: details $grant_access: İzin var $controller_class değeri: object(App\Controllers\HomeController)[46] private '_controller_name' (Core\Controller) => string 'Home' (length=4) private '_action_name' (Core\Controller) => string 'details' (length=7) public 'view' => object(Core\View)[43] public 'articles' => null public 'total' => null public 'heading' => null public 'errors' => null public 'user' => null public 'header' => null public 'users' => null public 'article' => null public 'msg' => null public 'limit' => null public 'page' => null public 'url' => null private '_site_title' => string 'BG MVC' (length=6) private '_content' => array (size=0) empty private '_current_content' => null private '_buffer' => null private '_layout' => string 'default' (length=7) private '_default_view_path' => string 'home/details' (length=12) public 'request' => object(Core\Request)[38]