ile

PHP ile içerik yönetim sistemi – 8 Herşeyi birleştirmeye başlayalım

tumblr_l25wkziSJ51qzyhb5o1_1280

 

Sıra geldi herşeyi birleştirmeye ve projemizin ilk bebek adımlarını atmasını sağlamaya. Yapmamız gerek bir kaç iş daha var ama biz projeyi birleştirmeye başlayalım.

dizin

 

burada config.codekit ve composer.json dosyaları hariç dizin yapısını lokal web sunucumuzun içinde (ipucu:xampp) oluşturalım. Klasör ismimiz Cms olsun. En önemli dosyamız şu anda index.php.

Diyelim ki projemizi, ftp ile sunucuya yükledik. Kullanıcı da adres çubuğuna sitemizin adresini yazdı. Ulaşacağı ilk sayfa index.php olacak haliyle. index.php dosyasının yapması gereken işler var. Sonuçta otelde resepsiyondaki görevliler gibi bişi o. Önce bizi tanımaya çalışacak, daha sonra bize yardımcı olacak ve istediğimiz yere götürecek.

url

index.php dosyasının yapması gereken işler sırayla;

  1. Kullanıcıyı tanımak. Kullanıcıya isteğini sormak. İsteğine göre gösterilecek sayfaları seçmek. Bunun için uygulama sınıfına başvurmak. Ondan cevap beklemek.
  2. Kullanıcıya nerede olduğunu söylemek. Admin panelindeyse admin, dış sitedeyse admin sayfalarını göstermek.
  3. Kullanıcının bi isteği yoksa, lobide rahat etmesini sağlamak. (Ana sayfa)
  4. Yani uygulama sınıfından gelen cevabı ekrana basmak.

Cms klasörünün içine index.php dosyamızı koyacağız. İçindeki kodlar şu şekilde olsun:

[code language=”php”]
<?php
require ‘Lib/Posts.php’;
require ‘Lib/Categories.php’;
require ‘Lib/Files.php’;

require ‘Config/config.inc.php’;
require ‘Lib/App.php’;

$app = new \Midori\Cms\App();
$app->connect($config[‘db’][‘host’],$config[‘db’][‘username’],$config[‘db’][‘password’],$config[‘db’][‘dbname’]);

if(strpos($_SERVER[‘REQUEST_URI’],$_SERVER[‘SCRIPT_NAME’])!==false){
$request = str_replace($_SERVER[‘SCRIPT_NAME’], “”, $_SERVER[‘REQUEST_URI’]);
}
else{
$request = “/Posts/”;
}

if(!empty($_POST))
{
$data = $_POST;
}
elseif(!empty($_FILES))
{
$data = $_FILES;
}
else{
$data = “”;
}
if(empty($request)){
$request = “/Posts/”;
}
echo $app->calculate($request,$data);

?>
[/code]

Kod sizi korkuttu mu? Korkutur. Normaldir. Ama daha önce yaptığımız gibi tek tek kodumuzun parçalarını inceleyelim.

  1. require metoduyla, ihtiyacımız olan sınıf dosyalarını dosyamıza çektik.
  2. Bunlar Lib klasörü içinde bulunan daha önce yarattığımız işlemleri yapan sınıf dosyalarımız ve veritabanı ayarlarını tutan config.inc.php. Ama meraklı bilişimci bu dosyayı oluşturmadın demeyin, bizde hiçbirşey eksik kalmaz.
  3. Daha sonra App sınıfı dosyasından   $app = new \Midori\Cms\App(); diyerek yeni uygulama sınıfı oluşturuyoruz. Peki başındaki bu \Midori\Cms\App() olayı ne? Hemen anlatayım:

Namespace

Diyelim ki bir yazılım yazdık, yazılımımızda da bir sürü sınıf kullandık. Örneğin, $file = new Files() diye bir sınıfımız var. Daha sonra başka bir kütüphane içerisinden bir sınıf kullanmamız gerekti, onun da adı Files. E ne olacak? Çakışacak. İşte bu çakışmayı önlemek için başına namespace dediğimiz bu kısaltmaları koyuyoruz, ki karışmasın. Bizde bunların adı \Midori\Cms. Bu sayede sınıflarımız gayet derli toplu oluyor. Peki kullanmasak olur muydu? Evet olurdu, ama projemiz çakışmalara da açık olurdu.

index.php dosyasında App diye bir sınıf var. Bu app sınıfı yazılımdaki her türlü işimizi yapmak zorunda olan bir tür işçi. Gelin App sınıfını inceleyim. Bu app sınıfını Cms altındaki Lib klasörüne kaydedelim. index.php bu app sınıfı ile bir nevi konuşuyor ve hangi durumda ne yapılması gerektiğini söylüyor. index.php resepsiyonist ise App sınıf otel müdürü gibi bişey.

hotel-staff-managers

 

Otel müdürünün yapması gereken bir takım işler olduğu gibi (hangi odaların kullanılabilir olduğuna karar vermek vs. gibi) App sınıfının da özel birtakım görevleri var. Appa metodu tüm diğer sınıfları kullanan, onlardan gerektiğinde objeler oluşturan sınıftır. Hadi kodu inceleyelim;

[code language=”php”]
<?php
/**
* Uygulamamızı çalıştıracak olan sınıf
*
* Sistemdeki tüm sınıfların içermeleri gereken veritabanı ve diğer bilgileri tutan sınıf.
*
* @author Midori Kocak <mtkocak@mtkocak.net>
*/

namespace Midori\Cms;

use Midori\Cms;
use \PDO;

class App{

/**
* Veritabanı bağlantısını tutacak olan değişken.
*
* @var PDO
*/
private $db = false;

/**
* Veritabanına bağlanmaya yarayan kurucu metod
*
* @param string host Veritabanı sunucusunun adresi
* @param string dbname Veritabanı adı
* @param string username Kullanıcı adı
* @param string password Parola
* @return string bağlanılabildiyse doğru, bağlanamadıysa hata mesajı döndürsün.
*/
public function connect($host, $username, $password, $dbname){
try {
return $this->db = new PDO(“mysql:host=”.$host.”;dbname=”.$dbname.””, “”.$username.””, “”.$password.””, array(
PDO::MYSQL_ATTR_INIT_COMMAND => “SET NAMES utf8”,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
} catch ( PDOException $e ){
return $e->getMessage();
}
}

public function injectRelatedData(){
$categories = new Categories();
$categories->connect($this->db);
return $categories->index();
}

public function calculate($request, $data)
{
// /posts/add gibi bir request geldi.
$params = split(“/”, $request);;
$className = __NAMESPACE__.’\\’.$params[1];
//call_user_func_array
$class = new $className();
$class->connect($this->db);
$class->getRelatedData($this->injectRelatedData());

if(empty($data))
{
if($params[2]!=null)
{
if(isset($params[3]))
{
$data = $class->$params[2]($params[3]);
}
else
{
$data = $class->$params[2]();
}
if($data[‘render’]!=false)
{
$content = array(‘related’=>$this->injectRelatedData(),’content’=>$this->render(‘./View/’.$params[1].’/’.mb_strtolower($params[2]).’.php’,$data));
return $this->render(‘./www/’.$data[‘template’].’.php’, $content);
}
else
{
$data = $class->show();
$content = array(‘related’=>$this->injectRelatedData(),’content’=>$this->render(‘./View/’.$params[1].’/show.php’,$data));
return $this->render(‘./www/’.$data[‘template’].’.php’, $content);
}
}
else{
$data = $class->index();
$content = array(‘related’=>$this->injectRelatedData(),’content’=>$this->render(‘./View/’.$params[1].’/index.php’,$data));
return $this->render(‘./www/’.$data[‘template’].’.php’, $content);
}
}
else{
call_user_func_array ( array($class, $params[2]), $data );
$data = $class->show();
$content = array(‘related’=>$this->injectRelatedData(),’content’=>$this->render(‘./View/’.$params[1].’/show.php’,$data));
return $this->render(‘./www/’.$data[‘template’].’.php’, $content);
}
// var_dump($params);
// $posts = new Posts();
// $posts->connect($this->db);
// return $posts->view(1);
}

public function render($file, $vars){

if (is_array($vars) && !empty($vars)) {
extract($vars);
}

ob_start();
include $file;
return ob_get_clean();
}

}
?>
[/code]

App.php dosyası biraz daha korkunç görünebilir, kabul ediyorum ama yine tek tek anlatacağım.

  1. Namespace kavramını anlatmıştım ya, önce namespace tanımladık. \Midori\Cms diye.
  2. App sınıfında PDO kütüphanesini kullanıyoruz. Bu yüzden use \PDO diyerek karışmayı da önlüyoruz.
  3. Diğer sınıfların içinde kullanacağımız veritabanı objesini burda private $db içinde tanımladık.
  4. connect yani bağlan metodu daha önce her sınıfta kullandığımız bağlanma metoduydu. Diğer tüm sınıflarda onu kullanmamak ve tek seferde çağırmak için burada tanımladık. Nasıl çalıştığını zaten biliyoruz.
  5. injectRelatedData, bağlı bilgileri ekle metodu. Örneğin girdiler yani posts sınıfı ile işlemler yapacağız. Girdi eklemek için kategorilerin listesine ihtiyacımız var. Burada kategorilerin listesini çekip o sınıfın içine göndermemiz gerek. Bu metodla bu işi hallediyoruz.
  6. En belalı metodumuz. Calculate yani hesapla metodu. Neredeyse tüm işleri yapan metodumuz. Bu metodda belki bilmediğimiz bir sürü kavram var ama korkmaya gerek yok hepsini tek tek inceleyeceğiz. Metod iki tane parametre almış. Bu parametrelerden biri $request diğer de $data. $request yani istek, kullanıcının bizden neyi istediği ve bu isteğe göre yapacağımız şeyleri belirten veridir. Örneğin istek olarak /Posts/View/1 gibi bişey gelirse, burdan kullanıcının 1 numaralı id’ye sahip olan Girdiği görmek istediğini şıp diye anlayabiliriz. $data ise, örneğin /Posts/add yani “Bu girdiyi sistmeme eklemek istiyorum” gibi bir istek varsa ve bununla birlikte bize kullanıcı girdi verisi yolladıysa, onu tutan değişkendir. Buradan bunu anlıyoruz.

Calculate metoduna devam etmeden, index.php dosyasında bu metodu nasıl çağırdığımıza bir geri dönelim.

[code language=”php”]
$app->connect($config[‘db’][‘host’],$config[‘db’][‘username’],$config[‘db’][‘password’],$config[‘db’][‘dbname’]);

if(strpos($_SERVER[‘REQUEST_URI’],$_SERVER[‘SCRIPT_NAME’])!==false){
$request = str_replace($_SERVER[‘SCRIPT_NAME’], “”, $_SERVER[‘REQUEST_URI’]);
}
else{
$request = “/Posts/”;
}

if(!empty($_POST))
{
$data = $_POST;
}
elseif(!empty($_FILES))
{
$data = $_FILES;
}
else{
$data = “”;
}
if(empty($request)){
$request = “/Posts/”;
}
echo $app->calculate($request,$data);
[/code]

index.php metodumuza geri döndük. Tek tek yaptıklarımızı incelemek için bir sürü zamanımız var. İçeride bilmediğimiz bir sürü yeni metod ve değişken var. Peki ne bunlar? Merak etmeyin, anlatıyorum:

  1. $config. yani ayarları tutan değişken. config.inc.php dosyasını include etmiştik yani yazılıma dahil etmiştik ya. Bu dosyadaki değişkenleri kullanıyoruz ki, programı her çalıştırdığımızda veritabanı bilgilerini girmeyelim, sadece bu dosyayı değiştirmemiz yeterli olsun.

config.inc.php dosyasını Cms dizini altında Config dizini içine kaydedelim ve içeriğine de şunları ekleyelim:

[code language=”php”]
<?php
/**
* Tüm sistemdeki ayarları buradan hallediyoruz.
*
* Veritabanına kaydetmediğimiz ve sürekli değişmeyecek
* olan veritabanı sunucusu, cache tipi gibi bilgileri
* bu dosyada saklayacağız.
*
* @author Midori Kocak <mtkocak@mtkocak.net>
*/

$config = array(
“db”=> array(
“dbname”=>”merakli”,
“host”=>”localhost”,
“username”=>”root”,
“password”=>”midori”
)
);

?>
[/code]

Burada ayarları tutan bir dizi oluşturduk ve tüm yazılımımızda sürekli aynı ayarları girmemek için kullanacağımız ayar değişkenlerini kaydedip kullanıyoruz.

Şu anda ayar dosyası oluşturmayı ve index.php ve App sınıfı kavramlarına giriş yaptık. Bir sonraki yazıda App.php sınıfını ve index.php içerisinde yaptığımız işlemleri ve kütüphanleremizde yaptığımız değişiklikleri incelemeye devam edeceğiz.

Kodun şu andaki son hali de şurda:

https://github.com/mtkocak/merakli/tree/cf5545a474f6ccf8b0ab521edb603629ba7d23ed

Yorumla

Yorum