Warning: Undefined array key "HTTP_ACCEPT_LANGUAGE" in /var/www/vhosts/bilgigunlugum.net/httpdocs/index.php on line 43
bgmvc

BG MVC Model View Controller eğitim serisi yayında...

Ana sayfa > Programlama > Bgmvc > Denetleyici sınıfları ve görüntüleri

Denetleyici sınıfları ve görüntüleri

App/controllers dizisi sınıfları

BG MVC sisteminde, app/controllers dizinindeki dosyalarda tanımlanmış controller sınıfından türetilmiş olan toplam 6 adet denetleyici sınıfı kullanılmaktadır.

App/controllers dizisi sınıfları fonksiyonlar tablosu

BG MVC denetleyici sınıf tanımlamaları, app/controllers dizinindeki .php uzantılı dosyalarda yapılmaktadır.

Denetleyici ve hareket fonksiyonları kullanımı

İstek yapılan URL satırı hangi denetleyici ve hareket fonksiyonunu içerirse içersin, tüm işlemler aşağıda belirtilen sıra dahilinde gerçekleşir:

  • Router sınıfı route() fonksiyonu içinde, call_user_func_array() fonksiyonu, yapılan isteğin URL satırında yer alan denetleyici sınıfı, hareket fonksiyonu ve parametre değerleri ile çağrılır.
  • Hareket fonksiyonu gerekli işlemleri yaptıktan sonra, View snıfı render() fonksiyonunu çağırır.
  • render() fonksiyonu ilgili görüntü dosyasını ve default.php çablon dosyasını görünüme dahil eder.
  • Görüntü dosyası içinde, View sınıfındaki start() ve end() fonksiyonları ile, default.php şablon dosyasında yer alacak olan içerik oluşturulur.
  • default.php dosyası içinde, sistemin ana HTML sayfası oluşturulur ve ekranda gösterilir.

Ön tanımlı denetleyici sınıfı

HomeController denetleyici sınıfı aşağıda gösterilen hareket fonksiyonlarından birisi ile çağrılır:

  • indexAction() -> index.php
  • detailsAction() -> details.php

Controller sınıfından türetilen HomeController sınıf nesnesi yoluyla erişim sağlanan Controller sınıfı içindeki $view değişkeni yoluyla View sınıfı içindeki render() fonksiyonunu kullanarak ilgili görüntü dosyasını ve şablon dosyasını tarayıcıda gösterir.

C:\wamp\www\bgmvc\app\controllers\HomeController.php


<?php 
namespace App\Controllers; // Namespace tanımı

use Core\{Controller, Router}; // Ana sınıf kullanımları
use App\Models\Articles; // Tablo model kullanımı

class HomeController extends Controller {

    public function indexAction($pageno=''){
		// Articles tablosundaki tüm sütunlar seçilerek kayıtlar id değeriyle büyükten küçüğe doğru sıralanır.
		$params = [
            'columns' => "*",
            'order' => 'articles.id DESC'
        ];  
        // Articles tablosundaki toplam kayıt sayısı
		$this->view->total = Articles::find_total($params);
		// $params dizisine 'limit' ve 'offset' değerleri eklenir, $pageno değerine göre $page değeri belirlenir.
		[$params, $page] = Articles::merge_with_pagination($params, $pageno, $this->view->total);
			
  	    // Controller sınıfı $view nesnesi yoluyla limit ve page değişkenleri oluşturulur. 
		$this->view->limit = $params['limit'];
	    $this->view->page = $page;
		
		// Articles tablosundaki tüm kayıt bilgileri articles adlı bir nesne dizisine aktarılır.
        $this->view->articles = Articles::find($params);
		// Web sayfası başlığını atama
		$this->view->heading = "Son makaleler";
        // Web sitesi başlığını atama
        $this->view->set_site_title('Son makaleler');
		
		// View sınıfı render() fonksiyonunu çağırma
		$this->view->render();
    }

    public function detailsAction($id) {
        // Articles tablosunda tüm sütunlar seçilerek kayıtlar id değerine sahip olan tek bir kayıt seçimi
		$params = [
            'columns' => "*",
			'conditions' => "articles.id = :id",
            'bind' => ['id' => $id]
        ];
		
		// Bir POST değeri varsa (Makalenin detaylı görüntülendiği sayfadaki seçme kutusundan farklı bir makale seçilmiştir)
		if($this->request->isPost()) {
		   // Javascript dosyasından okunan article_id değeri $params dizisinin 'bind' anahtarına atanır. 
		   $params['bind']['id'] = $this->request->get('article_id');
		   
		   // Articles tablosunda aranan kayıt bulunur ve $article değişkenine atanır.
		   $article = Articles::find_first($params);		  
		   
		   // $article değeri json_encode() fonksiyonu ile json formatına dönüştürülerek ekrana yazılır.
		   echo(json_encode($article));
		}	 		
		// Normal çalışma
		else {
		   // Articles tablosunda aranan kayıt bulunur ve $article değişkenine atanır.
		   $article = Articles::find_first($params);
		   // Makale bulunamazsa, hata sayfasına yönlendirme
		   if(!$article) Router::redirect('exceptions/index/noarticle');
		   // View sınıfı yoluyla article değişkeni oluşturma
		   $this->view->article = $article;

		   // 'conditions' ve 'bind anahtarları silinir.		   
		   unset($params['conditions']);
		   unset($params['bind']);
		   // 'order' anahtarı, id sütun değeri büyükten küçüğe doğru sıralanacak şekilde, eklenir.
		   $params['order'] = 'articles.id DESC';
		   
		   // Articles tablosundaki tüm kayıtlar $this->view->articles değişkenine atanır.
		   $this->view->articles = Articles::find($params);

		   // View sınıfı render() fonksiyonunu çağırma
		   $this->view->render();
		}
    }
}

indexAction fonksiyonu çağrıldıysa, sırayla aşağıdaki işlemler gerçekleştirilir:

  1. Tüm sütunlar seçilerek kayıtlar id değeriyle büyükten küçüğe doğru sıralanacak şekilde $params dizisine değer atanır.
  2. Articles sınıfı yoluyla Model sınıfının find_total() fonksiyonuna $params değişkeni parametre olarak geçirilerek, articles tablosundaki toplam kayıt sayısı alınır ve Controller sınıfı $view nesnesinin total adlı değişkenine atanır.
  3. Articles sınıfı yoluyla Model sınıfının merge_with_pagination() fonksiyonuna $params, $pageno, $this->view->total değerleri parametre olarak geçirilerek, $params dizisine 'limit' ve 'offset' değerleri eklenir, $pageno değerine göre $page değeri belirlenir.
  4. $params['limit'] değeri ile limit adlı ve $page değeri ile page adlı iki adet değişken, Controller sınıfı $view nesnesi yoluyla, oluşturulur.
  5. Articles sınıfı yoluyla Model sınıfının find() fonksiyonuna $params değişkeni parametre olarak geçirilerek, tüm kayıt bilgileri Controller sınıfı $view nesnesinin articles adlı dizisine aktarılır.
  6. Sayfa başlığı değeri Controller sınıfı $view nesnesinin heading adlı değişkenine atanır.
  7. Web sayfası başlığı, set_site_title() fonksiyonu ile Controller sınıfı $view nesnesinin $_site_title değişkenine atanır.
  8. Controller sınıfı $view nesnesi yoluyla View sınıfı render() fonksiyonu çağrılır.
  9. View sınıfı render() fonksiyonu içinde, app/views/home/index.php ve app/views/layout/default.php dosyaları sırasıyla görünüme dahil edilir.
    
    include($full_path);   // app/views/home/index.php
    include($layout_path); // app/views/layout/default.php
    
    

detailsAction fonksiyonu çağrıldıysa, sırayla aşağıdaki işlemler gerçekleştirilir:

  1. Tüm sütunlar seçilerek id değerine sahip olan tek bir kayıt seçilerek $params dizisine değer atanır.
  2. Denetleyiciye gönderilen bir POST değeri varsa, makalenin detaylı görüntülendiği sayfadaki seçme kutusundan farklı bir makale seçildiğini gösterir:
    • Request sınıfının get() fonksiyonu ile article_id değeri okunur ve $params dizisinin 'bind' anahtarına atanır.
    • Articles sınıfı yoluyla Model sınıfının find_first() fonksiyonuna $params değişkeni parametre olarak geçirilerek, articles tablosunda aranan kayıt bulunur ve $article değişkenine atanır.
    • $article değeri json_encode() fonksiyonu ile json formatına dönüştürülerek ekrana yazılır.
    • Geri döndürülen değer, main.js dosyasındaki getArticle_ajax() fonksiyonunda işlem yapılarak, makale görüntüleme sayfasındaki başlık ve içerik değerleri AJAX yöntemiyle güncellenir.
  3. Bir POST değeri yoksa:
    • Articles sınıfı yoluyla Model sınıfının find_first() fonksiyonuna $params değişkeni parametre olarak geçirilerek, articles tablosunda aranan kayıt bulunur ve $article değişkenine atanır.
    • $article değişken değeri, details.php görüntü dosyasında kullanılmak üzere, $this->view->article değişkenine atanır.
    • $params dizisinin 'conditions' ve 'bind anahtarları silinir, 'order' anahtarı ise, id sütun değeri büyükten küçüğe doğru sıralanacak şekilde, eklenir.
    • Articles sınıfı yoluyla Model sınıfının find() fonksiyonuna $params değişkeni parametre olarak geçirilerek, articles tablosundaki tüm kayıtlar, details.php görüntü dosyasında kullanılmak üzere, $this->view->articles değişkenine atanır.
  4. Controller sınıfı $view nesnesi yoluyla View sınıfı render() fonksiyonu çağrılır.
  5. View sınıfı render() fonksiyonu içinde, app/views/home/details.php ve app/views/layout/default.php dosyaları sırasıyla görünüme dahil edilir.
    
    include($full_path);   // app/views/home/details.php
    include($layout_path); // app/views/layout/default.php
    
    

HomeController index.php

C:\wamp\www\bgmvc\app\views\home\index.php


<?php 
  use Core\{H, Config}; // Ana sınıf kullanımları
?>

<?php $this->start('content'); ?> 

<?php 
if(Config::get('main_slide')) { 
   $this->inc('inc/main_slide');
}
?>

<div class="p-3">
	<nav class="navbar navbar-expand-lg bg-header">
	   <div class="container-fluid p-2">
	   
		  <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#MainNavbar" aria-controls="MainNavbar" aria-expanded="false" aria-label="Toggle navigation">
			<span class="navbar-toggler-icon"></span>
		  </button>
	   
		  <div class="collapse navbar-collapse" id="MainNavbar">
			
			<ul class="navbar-nav">
				<li><?=$this->heading?></li>
			</ul>
		  
			<ul class="navbar-nav ms-auto mb-2 mb-lg-0 bg-fontsm">
			    <?php // Sayfada gösterilecek kayıt sayısı seçimi ?>
				<form class="mt-2" action="<?=ROOT?><?=H::get_action()?>" method="post">
					<label class="me-2" for="records_limit">Kayıt sayısı</label>
					<select name="records_limit" id="records_limit" class="custom-select">
						<?php foreach([4, 6, 8, 10] as $limit) : ?>
						<option
							<?php if(isset($_SESSION['records_limit']) && $_SESSION['records_limit'] == $limit) echo 'selected'; ?>
							value="<?= $limit; ?>">
							<?= $limit; ?>
						</option>
						<?php endforeach; ?>
					</select>
				</form>
			</ul>
			
		  </div>
	   </div>
	</nav>
	
	<?php // Makalelerin gösterimi  ?>
	<div class="row row-cols-1 row-cols-md-3 row-cols-lg-4 row-cols-xl-5 row-cols-xxl-6 g-4">
	   <?php foreach($this->articles as $article): ?>
		 <div class="col">
			<div class="card h-100 shadow">
			  <div class="card-body">
				<h5 class="card-title"><?= $article->title ?></h5>
				<div class="bg-card-text mb-2"><?= html_entity_decode($article->body) ?></div>
				<a href="<?=ROOT?>home/details/<?=$article->id?>" class="text-info">Detaylar</a>
			  </div>
			</div>
		 </div>
       <?php endforeach; ?>
	</div>	
	
	<?php // Sayfa yapısı oluşturma ?>
	<?php $this->inc('inc/pager'); ?>

</div>

<?php $this->end(); ?>

index.php dosyasında sırayla aşağıdaki işlemler gerçekleştirilir:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. .env dosyasındaki main_slide değeri 1 ise, app/views/inc/main_slide.php dosyası görüntüye dahil edilir. Bu dosya ana sayfada slayt gösterimi sağlar.
  3. Ana sayfanın en üstünde yer alan, içinde sayfa başlığı ile sayfada gösterilecek kayıt sayısının belirlenmesini sağlayan bir seçme kutusu içeren, bir nav çubuğu oluşturur.
  4. Bir foreach döngüsü ile, $this->articles dizisi içinde yer alan kayıtları sırayla ekrana yazar.
  5. View sınıfının inc() fonksiyonu ile app/views/inc/pager.php sayfalama dosyasını görüntüye dahil ederek, sayfanın en altına yerleştirir.
  6. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

HomeController details.php

C:\wamp\www\bgmvc\app\views\home\details.php


<?php $this->start('content'); ?>

<div class="m-3">
	<select id="article_show" class="form-select form-select-sm mb-2 article_show" name="article_show" aria-label="Small select example">
		<?php foreach($this->articles as $article): ?>
		<option <?php echo ($article->id==$this->article->id) ? 'selected' : ''?> id="<?= $article->id ?>" class="" value="<?= $article->id ?>"><?= $article->title ?></option>
		<?php endforeach; ?>
	</select>

	<div class="bg-white rounded border shadow-sm p-3">
		<div class="row mb-4">
			<div class="col flex-grow-1">
				<h3 id="article_title"><?= html_entity_decode($this->article->title);?></h3>
			</div>
		</div>

		<div id="article_body">
			<?= html_entity_decode($this->article->body); ?>
		</div>
	</div>
</div>

<?php $this->end(); ?>

details.php dosyasında sırayla aşağıdaki işlemler gerçekleştirilir:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. Bir foreach döngüsü ile, $this->articles dizisi içinde yer alan kayıtların id değeri ve başlıklarını atayarak oluşturduğu bir select elemanını sayfanın en üstüne yerleştirir. Select elemanından yapılan seçme işleminde main.js dosyasındaki getArticle_ajax() fonksiyonu devreye girer ve seçilen makalenin id değerini kullanarak AJAX yöntemiyle veritabanı tablosundan okuduğu başlık ve içerik değerleriyle sayfa içeriğini yeniler.
  3. Makale başlığını ve içeriğini ekrana yazar.
  4. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

Activities denetleyici sınıfı

ActivitiesController denetleyici sınıfı aşağıda gösterilen hareket fonksiyonlarından birisi ile çağrılır:

  • softwareAction() -> software.php (Tüm kullanıcılar erişim sağlayabilir.)
  • codeAction() -> code.php (Kayıtlı kullanıcılar erişim sağlayabilir.)
  • designAction() -> design.php (Admin ve yetkilendirilmiş kullanıcılar erişim sağlayabilir. - Users tablosu acl değeri admin veya authorized olmalıdır.)

Yukarıdaki erişim kısıtlamaları app/views/inc/acl.json dosyası ile veritabanı users tablosundan okunan acl sütun değerine göre yapılmaktadır. Bir kullanıcının erişim yetkisi olmadığında, menü seçeneği hiç gösterilmez.

Menüde gösterilmeden yapılan erişim kısıtlaması için acl.json dosyası, menüde gösterilerek yapılan erişim kısıtlaması için ise ilgili hareket fonksiyonu kullanılır.

C:\wamp\www\bgmvc\app\controllers\ActivitiesController.php


<?php 
namespace App\Controllers;

use Core\{ Controller };

class ActivitiesController extends Controller {

    public function softwareAction(){
		$this->view->render();
    }
	
    public function codeAction(){
		$this->view->render();
    }

    public function designAction(){
		$this->view->render();
    }
}

ActivitiesController denetleyici sınıfına gelen isteğin hareket fonksiyonuna karşılık gelen aşağıdaki görünüm dosyalarından birini görünüme dahil eder. Görünüm dosyaları:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. İçeriği ekrana yazar.
  3. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

ActivitiesController software.php

C:\wamp\www\bgmvc\app\views\activities\software.php


<?php $this->set_site_title('Yazılım hizmetleri'); ?>
<?php $this->start('content'); ?>

<div class="row m-4">
	<div class="text-center p-4 border rounded">
		 <h2 class="">Yazılım satış hizmetleri</h2>
		 <hr>
		 <img class="mx-auto mb-4 img-fluid rounded" src="<?=ROOT?>public/images/software.png">
		 <p>İşletim sistemleri, ofis programları, antivirüs programları ve kişiye özel özel paket program satışı.</p>
	</div>
</div>

<?php $this->end(); ?>

ActivitiesController code.php

C:\wamp\www\bgmvc\app\views\activities\code.php


<?php $this->set_site_title('Kodlama eğitimleri'); ?>
<?php $this->start('content'); ?>

<div class="row m-4">
	<div class="text-center p-4 border rounded">
		 <h2 class="">Kodlama eğitimleri</h2>
		 <hr>
		 <img class="mx-auto mb-4 img-fluid rounded" src="<?=ROOT?>public/images/code.png">
		 <p>Programlama, web programlama ve tasarım faaliyetlerimizle hizmetinizdeyiz.</p>
		 <p>Programlama alanında C, C++, Gömülü programlama, MySQL, Windows API, Jva, Android, Python ve yapay zekada kullanımı konuları, web programlama alanında ise html, css, MVC, CMS ve Symfony Framework konuları işlenmektedir.</p>
	</div>
</div>

<?php $this->end(); ?>

ActivitiesController design.php

C:\wamp\www\bgmvc\app\views\activities\design.php


<?php $this->set_site_title('Web tasarım hizmetleri'); ?>
<?php $this->start('content'); ?>

<div class="row m-4">
	<div class="text-center p-4 border rounded">
		 <h2 class="">Web tasarım hizmetleri</h2>
		 <hr>
		 <img class="mx-auto mb-4 img-fluid rounded" src="<?=ROOT?>public/images/design.png">
		 <p>Statik veya dinamik içeriğe sahip sıfırdan tasarlanmış veya hazır içerik yönetim sistemleriyle hazırlanmış web site kurulumu ve takibi.</p>
	</div>
</div>

<?php $this->end(); ?>

Codes denetleyici sınıfı

CodesController denetleyici sınıfı indexAction hareket fonksiyonu ile çağrılır.

CodesController index.php dosyasına sadece, admin ve yetkilendirilmiş kullanıcılar erişim sağlayabilir (Users tablosu acl değeri admin veya authorized).

Menüde gösterilmeden yapılan erişim kısıtlaması için acl.json dosyası, menüde gösterilerek yapılan erişim kısıtlaması için ise ilgili hareket fonksiyonu kullanılır.

C:\wamp\www\bgmvc\app\controllers\CodesController.php


<?php
namespace App\Controllers;

use Core\{ Controller, Router };
use App\Models\Users;

class CodesController extends Controller {

    public function indexAction() {
		$user = Users::get_current_user();
		
		// Kullanıcı kayıtlı ise
		if($user) {
		   // Kullanıcı admin veya yetkili ise
		   if($user->acl=='admin' || $user->acl=='authorized') {
			  $this->view->render();
		   }
		   else {
			  Router::redirect('exceptions/index/noauthorized');
		   }   
		}
		else {
		   Router::redirect('exceptions/index/nouser');
		}	
    }
}

indexAction() fonksiyonu çağrıldığında, kullanıcı admin veya yetkili ise, index.php görünüm dosyasında aşağıdaki işlemler gerçekleştirilir:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. İçeriği ekrana yazar.
  3. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

CodesController index.php

C:\wamp\www\bgmvc\app\views\codes\index.php


<?php $this->set_site_title('Kod örnekleri'); ?>
<?php $this->start('content'); ?>

<div class="row m-4">
	<div class="text-center p-4 border rounded">
		 <h2 class="">Kod örnekleri</h2>
		 <hr>
		 <img class="mx-auto mb-4 img-fluid rounded" src="<?=ROOT?>public/images/sample_codes.png">
		 <p>Bu sayfada yer alan örnek yazılım kodlarına sadece yetkilendirilmiş kullanıcılar erişim sağlayabilir.</p>
	</div>
</div>

<?php $this->end(); ?>

About denetleyici sınıfı

AboutController denetleyici sınıfı indexAction hareket fonksiyonu ile çağrılır.

C:\wamp\www\bgmvc\app\views\about\index.php


<?php 

namespace App\Controllers;

use Core\{ Controller};

class AboutController extends Controller {

    public function indexAction(){
		$this->view->render('about/index');
    }
}

indexAction() fonksiyonu çağrıldığında, kullanıcı admin veya yetkili ise, index.php görünüm dosyasında aşağıdaki işlemler gerçekleştirilir:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. İçeriği ekrana yazar.
  3. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

AboutController index.php

C:\wamp\www\bgmvc\app\views\about\index.php


<?php $this->set_site_title('Hakkımızda'); ?>
<?php $this->start('content'); ?>

<div class="row m-4">
	<div class="text-center p-4 border rounded">
		 <h2 class="">Hakkımızda</h2>
		 <hr>
		 <img class="mx-auto border rounded mb-4" src="<?=ROOT?>public/images/logo.png">
		 <p>BG MVC, MVC (Model View Controller - Model Görünüm Denetleyici) alt yapısı üzerine tasarlanmış, veri tabanı işlemlerini PDO (PHP Data Objects - PHP Veri Nesneleri) ile gerçekleştiren, PHP kodlama ile oluşturulmuş basit bir içerik sistemidir.</p>
		 <p>BG MVC kullanarak, bir web sitesinin alt yapısını oluşturabilirsiniz.</p>
	</div>
</div>

<?php $this->end(); ?>

Register denetleyici sınıfı

RegisterController denetleyici sınıfı aşağıda gösterilen hareket fonksiyonlarından birisi ile çağrılır:

  • registerAction() -> register.php
  • loginAction() -> login.php
  • logoutAction()

C:\wamp\www\bgmvc\app\controllers\RegisterController.php


<?php 
namespace App\Controllers; // Namespace tanımı

use Core\{Controller, Session, Router}; // Ana sınıf kullanımları
use App\Models\Users; // Tablo model kullanımı

class RegisterController extends Controller {
    
	public function registerAction() {
		        
        $user = new Users(); // Yeni bir kullanıcı nesnesi oluşturma

        // Form gönderilmiş ise
		if($this->request->isPost()){
		   Session::csrf_check(); // Token kontrolü
           // Users tablosundaki sütun değerlerinin adını içeren bir dizi oluşturma
		   $fields = ['fname', 'lname', 'email', 'acl', 'password', 'confirm'];
           // $user nesnesine form değerlerini atama
		   foreach($fields as $field) {
			  // acl alanı ise 'user' değeri atama
			  if($field=='acl') {
				 $user->{$field} = 'user';
			  }	
              else { 
				 $user->{$field} = $this->request->get($field);
			  }
           }

		   // $user nesnesini users tablosuna kaydetme
           if($user->save()) {
              // Mesaj oluşturma
			  $msg = "Kullanıcı oluşturuldu";
			  Session::msg($msg, 'success');
			  // Giriş sayfasına yönlendirme
              Router::redirect('register/login');
           }
        }
		
		// $user nesne değerlerini görüntü dosyasına aktarma 
        $this->view->user = $user;
		// Hataları görüntü dosyasına aktarma
        $this->view->errors = $user->get_errors();
		// register.php dosyasını çağırma
        $this->view->render();		
    }

    public function loginAction() {
        $user = new Users(); // Yeni bir kullanıcı nesnesi oluşturma
        $isError = true;

        // Form gönderilmiş ise
		if($this->request->isPost()) {
            Session::csrf_check(); // Token kontrolü
			// Form kullanıcı giriş değerlerini $users nesnesine aktarma
            $user->email = $this->request->get('email');
            $user->password = $this->request->get('password');
            $user->remember = $this->request->get('remember');
            // Users sınıfı ile giriş değerlerini doğrulama
			$user->validate_login();
            
			// $user nesnesi hatası yoksa
			if(empty($user->get_errors())){
               // Kullanıcı giriş değerleri ile Users sınıfı üzerinden Model sınıfı find_first() fonksiyonu ile kayıt alma 
			   $u = Users::find_first([
                    'conditions' => "email = :email", 
                    'bind' => ['email' => $this->request->get('email')]
               ]);
               
			   // Kayıt varsa
			   if($u) {
                  // Kullanıcının girdiği parola ile Users tablosundan okunan parolayı doğrulama
				  $verified = password_verify($this->request->get('password'), $u->password);
                  
				  // Parolalar aynı ise
				  if($verified) {
                     $isError = false;
                     $remember = $this->request->get('remember') == 'on';
                     // Users sınıfı login() fonksiyonu ile bağlanma
					 $u->login($remember);
                     // Router sınıfı redirect() fonksiyonu ile login sayfasına erişim
					 Router::redirect('');
                  }
               }
            }
            
			// Hata varsa
			if($isError) {
               $user->set_error('email', 'E-posta veya parola hatalı. Lütfen tekrar deneyin.');
               $user->set_error('password', '');
            }
        }
		
        // Hataları errors değişkenine atama 
		$this->view->errors = $user->get_errors();
		// Kullanıcı nesnesini user değişkenine atama
        $this->view->user = $user;
		// login.php dosyasını çağırma
        $this->view->render();
    }

    public function logoutAction() {
        global $current_user;
        
		if($current_user) {
		   // Kullanıcı giriş yapmış ise, çıkış yapma	
           $current_user->logout();
        }
        
		// Giriş sayfasına yönlendirme
		Router::redirect('register/login');
    }
}

registerAction fonksiyonu çağrıldıysa, sırayla aşağıdaki işlemler gerçekleştirilir:

  1. Users sınıfından $user adlı yeni bir kullanıcı nesnesi oluşturulur.
  2. Form gönderilmiş ise:
    • Session sınıfı csrf_check() fonksiyonu ile token kontrolü yapılır.
    • Users tablosundaki sütun değerlerinin adını içeren $fields adlı bir dizi oluşturulur.
    • $user nesnesine form değerleri atanır. acl alanı ise 'user' değeri atanır.
    • $user nesnesi users tablosuna kaydedilir.
    • Kayıt işlemi başarılı olursa, mesaj oluşturulur ve giriş sayfasına yönlendirme yapılır.
  3. user adlı bir değişken oluşturularak, $user nesne değerleri görüntü dosyasına aktarılır.
  4. errors adlı bir değişken oluşturularak, hata değerleri görüntü dosyasına aktarılır.
  5. Controller sınıfı $view nesnesi yoluyla View sınıfı render() fonksiyonu çağrılır.
  6. View sınıfı render() fonksiyonu içinde, app/views/register/register.php ve app/views/layout/default.php dosyaları sırasıyla görünüme dahil edilir.
    
    include($full_path);   // app/views/register/register.php
    include($layout_path); // app/views/layout/default.php
    
    

loginAction fonksiyonu çağrıldıysa, sırayla aşağıdaki işlemler gerçekleştirilir:

  1. Users sınıfından $user adlı yeni bir kullanıcı nesnesi oluşturulur.
  2. Form gönderilmiş ise:
    • Session sınıfı csrf_check() fonksiyonu ile token kontrolü yapılır.
    • Form kullanıcı giriş değerleri $users nesnesine aktarılır.
    • Users sınıfı validate_login() fonksiyonu ile giriş değerleri doğrulanır.
    • $user nesnesi hatası yoksa,
      • Kullanıcı giriş değerleri ile Users sınıfı üzerinden Model sınıfı find_first() fonksiyonu ile kayıt okunur.
      • Kayıt varsa, kullanıcının girdiği parola ile Users tablosundan okunan parolayı doğrulanır. Parolalar aynı ise, Users sınıfı login() fonksiyonu ile bağlantı yapılır. Router sınıfı redirect() fonksiyonu ile login sayfasına erişim sağlanır.
  3. errors adlı bir değişken oluşturularak, hata değerleri görüntü dosyasına aktarılır.
  4. user adlı bir değişken oluşturularak, $user nesne değerleri görüntü dosyasına aktarılır.
  5. Controller sınıfı $view nesnesi yoluyla View sınıfı render() fonksiyonu çağrılır.
  6. View sınıfı render() fonksiyonu içinde, app/views/register/login.php ve app/views/layout/default.php dosyaları sırasıyla görünüme dahil edilir.
    
    include($full_path);   // app/views/register/login.php
    include($layout_path); // app/views/layout/default.php
    
    

logoutAction fonksiyonu çağrıldıysa, sırayla aşağıdaki işlemler gerçekleştirilir:

  1. Kullanıcı giriş yapmış ise, Users snıfı logout() fonksiyonu ile çıkış yapılır.
  2. Giriş sayfasına yönlendirme yapılır.

RegisterController register.php

C:\wamp\www\bgmvc\app\views\register\register.php


<?php use Core\FH; ?>
<?php $this->start('content'); ?>
<div class="row m-4">
    <div class="col-12 col-md-6 col-xl-4 bg-white rounded border shadow-sm p-4 mx-auto">
		<h4 class="p-2 mb-2 bg-body-secondary rounded border border-primary-subtle text-center shadow-sm">Kayıt</h4>

        <form action="" method="POST">
            <?= FH::csrf_field();?>
            <div class="row">
                <?= FH::input_block('Adı', 'fname', $this->user->fname, ['class' => 'form-control'], ['class' => 'mb-36'], $this->errors); ?>
                <?= FH::input_block('Soyadı', 'lname', $this->user->lname, ['class' => 'form-control'], ['class' => 'mb-3'], $this->errors); ?>
                <?= FH::input_block('E-posta', 'email', $this->user->email, ['class' => 'form-control', 'type' => 'email'], ['class' => 'mb-3'], $this->errors); ?>
            </div>

            <div class="row">
                <?= FH::input_block('Parola', 'password', '', ['class' => 'form-control', 'type' => 'password'], ['class' => 'mb-3'], $this->errors); ?>
                <?= FH::input_block('Parola onayı', 'confirm', '', ['class' => 'form-control', 'type' => 'password'], ['class' => 'mb-3'], $this->errors); ?>
            </div>
			
            <div class="row">
                <div class="col">
				    <a href="<?=ROOT?>register/login">Giriş yap</a>
                </div>
            </div>			

            <div class="text-end">
                <a href="<?=ROOT?>register/register" class="btn btn-secondary">İptal et</a>
                <input class="btn btn-primary" value="Kaydet" type="submit" />
            </div>
        </form>
    </div>
</div>
<?php $this->end(); ?>

register.php görünüm dosyasında aşağıdaki işlemler gerçekleştirilir:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. FH sınıfı csrf_field() fonksiyonu ile token oluşturulur.
  3. 'Kayıt' ifadesi başlık olarak yazılır.
  4. Adı, soyadı ve e-posta, parola ve parola onayı bölümleri kullanıcı girişi için hazırlanır.
  5. 'Kaydet' ve 'İptal et' butonları ile 'Giriş yap' bağlantısı hazırlanır.
  6. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

RegisterController login.php

C:\wamp\www\bgmvc\app\views\register\login.php


<?php 
use Core\FH; 
use App\Models\Users;
?>
<?php $this->start('content');?> 

<div class="row m-4">
    <div class="col-12 col-md-6 col-xl-4 bg-white rounded border shadow-sm p-4 mx-auto">
        <h4 class="p-2 mb-2 bg-body-secondary rounded border border-primary-subtle text-center shadow-sm">Giriş</h4>

        <form method="POST">
            <?= FH::csrf_field(); ?>
            <div class="row">
                <?= FH::input_block('E-posta', 'email', $this->user->email,['class' => 'form-control', 'type'=>'text'],['class' => 'mb-3 '], $this->errors); ?>
                <?= FH::input_block('Parola', 'password', $this->user->password, ['class' => 'form-control', 'type' => 'password'], ['class' => 'mb-3'], $this->errors); ?>
            </div>

            <div class="row">
                <div class="col">
                    <?= FH::check('Beni hatırla', 'remember', $this->user->remember == 'on', ['class' => 'form-check-input'], ['class' => 'mb-3 form-check'], $this->errors); ?>
				    <a href="<?=ROOT?>register/register">Kayıt ol</a>
                </div>
            </div>

            <div class="text-end">
                <a href="<?=ROOT?>register/login" class="btn btn-secondary">İptal et</a>
                <input class="btn btn-primary" value="Giriş yap" type="submit" />
            </div>
        </form>
    </div>
</div>
<?php $this->end(); ?>

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. FH sınıfı csrf_field() fonksiyonu ile token oluşturulur.
  3. 'Giriş' ifadesi başlık olarak yazılır.
  4. E-posta, parola ve 'Beni hatırla' bölümleri kullanıcı girişi için hazırlanır.
  5. 'Giriş yap' ve 'İptal et' butonları ile 'Kayıt ol' bağlantısı hazırlanır.
  6. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.

Exceptions denetleyici sınıfı

ExceptionsController denetleyici sınıfı indexAction hareket fonksiyonu ile çağrılır.

C:\wamp\www\bgmvc\app\controllers\ExceptionsController.php


<?php
namespace App\Controllers;
use Core\Controller;

class ExceptionsController extends Controller {

  public function indexAction($msg='noaccess') {	 
	
    $msg_txt = '';

	switch($msg) {
		 case 'nopage':	
			  $msg_txt = 'Bu sayfa mevcut değil!';
			  break;
		 case 'noaccess':	
			  $msg_txt = 'Bu sayfaya erişim yetkiniz yok!';
			  break;
		 case 'badtoken':	
			  $msg_txt = 'Token değeriniz bozulmuş!';
			  break;
		 case 'noarticle':	
			  $msg_txt = 'Makale mevcut değil!';
			  break;	
		 case 'noauthorized':	
			  $msg_txt = 'Bu sayfaya erişim özel yetki gerektirir!';
			  break;	
		 case 'nouser':	
			  $msg_txt = 'Kullanıcı kayıtlı değil!';
			  break;
			  
		 case 'noview':	
			  $msg_txt = 'Görünüm mevcut değil!';
			  break;		  
		 case 'notemplate':	
			  $msg_txt = 'Şablon mevcut değil!';
			  break;		  
		 case 'nokey':	
			  $msg_txt = 'Start metodu geçerli bir anahtar yok!';
			  break;		  
		 case 'nostart':	
			  $msg_txt = 'Start metodu çalıştırılmamış!';
			  break;
	}  

    $this->view->msg = $msg;
    $this->view->msg_txt = $msg_txt;	  	
	
    $this->view->render('exceptions/index');
  }
}

indexAction() fonksiyonunda aşağıdaki işlemler gerçekleştirilir:

  1. Parametre olarak geçirilen $msg değerine bağlı olarak $msg_txt değişkenine bir karakter dizisi atar.
  2. Görüntü dosyasında kullanılmak üzere, msg adlı bir değişken oluşturarak $msg değişken değerini ve msg_txt adlı bir değişken oluşturarak $msg_txt değişken değerini atar.
  3. View sınıfı render() fonksiyonunu çağırır.
  4. View sınıfı render() fonksiyonu içinde, app/views/exceptions/index.php ve app/views/layout/default.php dosyaları sırasıyla görünüme dahil edilir.
    
    include($full_path);   // app/views/exceptions/index.php
    include($layout_path); // app/views/layout/default.php
    
    

ExceptionsController index.php

C:\wamp\www\bgmvc\app\views\exceptions\index.php


<?php $this->set_site_title('Giriş sınırlaması'); ?>
<?php $this->start('content'); ?>

<div class="row m-4">
	<div class="col-12 col-lg-6 text-center p-4 border border-warning rounded mx-auto">
		 <h2 class="mb-4 p-2 rounded bg-secondary-subtle border border-secondary-subtle"><?=$this->msg_txt?></h2>
		 <div class="bg-exception mb-4">
		     <img class="" src="<?=ROOT?>public/images/<?=$this->msg?>.png">
		 </div>
		 <div>
             <a href="<?=ROOT?>" class="btn btn-warning">Ana sayfa</a>
         </div>
	</div>
</div>

<?php $this->end(); ?>

index.php görünüm dosyasında aşağıdaki işlemler gerçekleştirilir:

  1. View sınıfı start() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik başlangıcını tanımlar.
  2. msg_txt değişkenini başlık olarak ekrana yazar.
  3. msg değişkeni ile ilgili bir resim oluşturur.
  4. 'Ana sayfa' bağlantısı oluşturur.
  5. View sınıfı end() fonksiyonu ile default.php şablon dosyasında kullanılacak içerik sonunu tanımlar.