Cuma, 4 Mayıs 2012

CodeIgniter ile Obje Tabanlı Programlama

 

CodeIgniter versiyon 2.0'dan sonra Driver isimli yeni kütüphanesi, ebeveyn ve çocuklar (parent and childs) kullanımı yöntemi ile uygulamaya sokmuştu. Driver kütüphanesinin kullanımı bazı durumlarda çok pratik olmasına karşın, bazı durumlarda ihtiyaca cevap verememektedir.

Driver kütüphanesinin çalışma prensibi, temelde birbirinden farklı ve bağımsız sınıfların bir ana sınıf ile birleşmesine dayanır. Ana sınıf, çocuk sınıflar ile konuşabilmesine karşın, çocuk sınıflar kendileri içinde konuşamazlar.

Driver kütüphanesinin çalışma şeklini başka bir yazıya bırakıp, kendi yazacağımız bir kütüphanede fabrika desenini nasıl uygulayacağımızı görelim. Diyelim ki, elimizde method isimleri birebir aynı olan ama içeriği farklı olan iki kütüphanemiz olsun. Örneğin, Amazon`un Simple Storage Service (S3) ve Elastic Compute Cloud (Ec2) hizmetlerini düşünelim. application/libraries dizini altına amazon.php isimli kütüphanemizi ekeleyim, amazon isimli bir dizin açalım.

Yazacağımız kütüphanenin, kullanıcının seçimine göre bu iki kütüphaneden (Ec2 ya da S3) birindeki methodları çalıştırsın isteriz. Önce applications/libraries/amazon dizini altına abstract.amazon.php dosyasını açarak, S3 ve EC2 dosyalarında kullanacağımız ortak metotları listeleyelim:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

include_once 's3.amazon.php';
include_once 'ec2.amazon.php';

abstract class FB_amazon {
   
   abstract public function hello();
   abstract public function get_info();

}

Abstract dosyasında öncelikle aynı dizin içinde bulunan S3 ve Ec2 kütüphanelerini include ediyoruz. Daha sonra FB_amazon isimli sınıfımızda diper iki sınıftada bulunan ortak metotları yazıyoruz. İsterseniz abstract yerine implement yönetmini de kullanabilirsiniz.

S3 ve Ec2 kütüphanelerimiz ise kendi içlerinde, abstract dosyasında işaret ettiğimiz metotlara sahiptirler. Application/libraries/amazon dizini altına iki kütüphaneyi açalım. s3.amazon.php dosyası:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class S3 extends FB_amazon {
   
   public function hello(){
   
  echo "here is s3";
   }
   
   
   public function get_info(){
   
  echo "here is inside of s3";
   }   

}
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Ec2 extends FB_amazon {
   
   public function hello(){
   
  echo "here is ec";
   }
   
   public function get_info(){
   
  echo "here is inside of ec";
   }   

}

Yukarıdaki yapı ile kütüphanelerimizi hazırladık. Şimdi ise, application/libraries altında yer alan ve CodeIgniter içinden çağıracağımız sınıfımızı yazalım. Abstract sınıfı doğrudan CodeIgniter içinden çağrılamayacağı için bu sınıfı yazmak zorundayız. application/libraries dizini altındaki amazon.php dosyası:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Amazon {
   
   public function __construct()
   {
  $CI = & get_instance();
  log_message('Debug', 'Amazon strategy class is loaded.');
   }

   public function load($library)
   {
  include_once 'amazon/abstract.amazon.php';
  
  $lib = ucfirst($library);
  
  return new $lib();
 
 }
}

Yukarıdaki sınıfta, abstract sınıfımızı include ettikten sonta, kullanıcının seçtiği sınıf adı (S3 ya da Ec2) değişkeni ilk harfi büyütülüp, yeni bir sınıf şeklinde yüklenerek geri gönderilir. Böylece eğer kullanıcı S2 ü seçtiyse, s3.amazon.php isimli dosyadaki metotları kullanır hale gelir.

Son adımda ise controller dosyamıza bakalım. application/controllers dizini altına site.php ismi ile kaydettiğimiz dosyamızın içeriği:

<?php

class Site extends CI_Controller {

 public $amazon;

 function __construct() {
 
        parent::__construct();
  
  $this->load->library('amazon');
  
  $lib = $this->uri->segment(3);
   
  $this->amazon = $this->amazon->load($lib);
  
    }

   public function hello() {
  
  $this->amazon->hello();
 }
 
 public function get() {
 
  $this->amazon->get_info();
  
 }
}

Öncelikle amazon kütüphanesi çağrılır ve kullanıcının URL`den belirlediği kütüphane ismi alınarak yüklenir (http://localhost/my_site/site/hello/s3). Kullanıcının seçtiği kütüphane adına uygun olarak ekrana bastırılan sonuç görüntüleri değişecektir.

Yukarıdaki örnekte tasarım desenlerine uygun olarak hazırlanmiş bir obje tabanlı kütüphaneninin (oop), CodeIgniter`da nasıl çalıştırılacağını gördük. Burada dikkat edilmesi gereken konulardan biri, abstract dosyasında kullandığımız sınıf adının CodeIgniter için çağırdığımız sınıftan farklı olmasıdır (FB_amazon ile amazon sınıfı gibi). Bir diğer önemli konu ise, yüklediğimiz kütüphaneyi tekrar aynı isimli değişken sınıfına göndermemiz gerekliliğidir (site.php dosyasındaki $this->amazon = $this->amazon->load($lib); satırı). Aksi taktirde, yüklenen sınıfın özelliklerinin tamamını kullanamayız.

Bu yazı ile sadece MVC desenine bağlı kalmadan da CodeIgniter ile programlama yapabileceğimizi anlatmak istedim. Kendi oluşturacağımız kütüphanelerde kullanacağımız tasarım desenleri yardımı ile CodeIgniter gibi güvenli ve stabil bir Php çatısının avantajlarını kullanarak programlarımızı yazabiliriz. Fazla karıştırmadan ana hatları ile anlatmaya çalıştığım bu yazıyı, tekrar bu gözle yeniden okumanızı öneririm.

Yazıda anlatılan dokümanları buradan indirebilirsiniz.

Perşembe, 19 Nisan 2012

CIHBS - HMVC ve Twitter Bootstrap ile Oluşturulmuş CI Şablonu

 

Önceki yazılarımızda HMVC modüler yapısının nasıl kullanılacağını göstermiş, kullanıcı ve yönetici girişlerinin nasıl yapılacağını anlatmıştık. Bu yazıda ise github üzerine açtığım CIHBS isimli şablon reposunun nasıl kullanacağınız anlatılacaktır.

CIHBS kısaltması, CodeIgniter Hmvc ve BootStrap kelimelerinin baş harfelrinden oluşmaktadır. CodeIgniter 2.1 versiyonu ile hazırlaığım bu şablon, HMVC ile Twitter Bootstrap V2.0.2 arayüzünü içerir. Dizin yapısı aşağıdaki yapıya benzerdir:

 
/
    application/
        config/
        controllers/
             auth.php
        modules/
             dashboard/
                 controllers/
                     admin.php
                     dashboard.php
                 models/
                     dashboard.php
                 views/
                     admin/
                         index.php
                         form.php
             welcome/
                  controllers/
                      admin.php
                      welcome.php
                  models/
                      welcome_model.php
                  views/
      welcome_view.php
                     admin/
                         index.php
                         form.php
          views/
              layout_view.php
     header_view.php
     footer_view.php
              meta_view.php
      system/
      index.php

Bu yapıda gördüğünüz üzere, giriş-çıkış kontrolü application/controllers/auth.php dosyası üzerinden sağlanır. Her bir modül ise, application/modules dizini altında kendi ismi ile MVC yapısına sahiptir.

Kullanıcının erişim yetkisi, controller dosyasının construct modülünde kontrol edilir:

 
    function __construct() {
 
        parent::__construct();

  if(! $this->hmvc_auth->get('logged_in')) exit('Yetkili değilsiniz');
 }

Eğer kullanıcımızın rolü "admin" ise (veritabanınaki "role" tablosu değeri "a" ise), her controller dizini içindeki admin.php dosyasına erişilebilir. Admin kontrolü ise yine construct mödülünde kontrol edilir:

 
    function __construct()
    {
        parent::__construct();

  if(! $this->hmvc_auth->is_admin()) exit('Admin degilsiniz!');
  
 }

Yönetici paneline erişim için gerekli yönlendirmeler ise Application/config/routes.php dosyasından yapılır:

 

$route['(login|logout)'] = "auth/$1";

$route['admin/([a-zA-Z_-]+)/(:any)'] = '$1/admin/$2';

$route['admin/([a-zA-Z_-]+)'] = '$1/admin/index';

Twitter Bootstrap arayüzü de hem kullanım kolaylığı, hem de estetik olması açısından bu şablona giydirildi. Bu arayüz temel olarak 3 ana parçaya ayrıldı: header, footer, meta view. Her controller dosyasında bulunan render methodu ile controller'a özgü parçalar bir araya getirilip, ekrana bastırılmaktadır.

Github üzerinde herkese açık olan CIHBS reposu, şablon özelliğini koruyacak şekilde siz programcıların katkılarını beklemektedir.

Cuma, 13 Nisan 2012

Adres Satırında Türkçe Karakter Sorunu

 

Adres satırında link olarak kullandığımız kelimelerin türkçe olması CodeIgniter'da soruna yolaçar. Bunu önlemek için, link olarak kullanacağımız Türkçe harfleri ingilizce karşılıklarına göre çevirmemiz gerekir. Bu işlem için bir çok farklı yolu deneyebilirsiniz. Bu yazıda url_helper ve text_helper kullanarak, bu işlemi CodeIgniter 2.0 ve üzeri versiyonlar için nasıl yapacağımızı bulacaksınız.

CodeIgniter'ın bu işlem için url_helper sınıfında bulunan "url_title" isimli bir fonksiyonu vardır. Config/autoload.php dosyamızda açılşta yüklettiğimiz url helper'ından sonra, controller ya da view dosyalarımızda şöyle kullanırız

$title = "Akşam için Ümraniye İle Şişli çevresinde yağış görülüyor, Önleminizi aldınız mı?";

$url_title = url_title($title);

// Sonuç: Akam-iin-mraniye-le-ili-evresinde-ya-grlyor-nleminizi-aldnz-m

Fonksiyona gönderdiğimiz kelimeler HTML başlıklarından, tırnaklardan ve boşluklar arındırılarak adres satırına göndermeye hazır hale getirilir. Ancak kelmeler içinde geçen Türkçe karakterler çevrilmez, bunu çevirmek için ise text_helper dosyasını autload.php ile yükledikten sonra convert_accented_characters fonksiyonunu kullanalım.

$title = "Akşam için Ümraniye İle Şişli çevresinde yağış görülüyor, Önleminizi aldınız mı?";

$url_title = url_title(convert_accented_characters($title));

// Sonuç: Aksam-icin-Uemraniye-Ile-Sisli-cevresinde-yagis-goeruelueyor-Oenleminizi-aldiniz-mi

Sonuç fena gibi değil ancak fark ettiyseniz, Ü ve Ö harflerinde bir sorun oluşmuş. Bunu düzeltmenin yolu ise config/foreign_chars.php dosyasını düzeltmekten geçiyor. Bu dosyadaki 12, 13, 15 ve 16. satırlardaki karşılıkları aşağıdaki gibi düzeltince:

 '/ö|œ/' => 'o', //12. satır
 '/ü/' => 'u',//13. satır
 '/Ü/' => 'U',//15. satır
 '/Ö/' => 'O',//16. satır

Sonuç istediğimiz gibi çıkacaktır:

Aksam-icin-Umraniye-Ile-Sisli-cevresinde-yagis-goruluyor-Onleminizi-aldiniz-mi

Eğer adres satırında bu cümlenin ilk 50 karakterini bastırmak isterseniz, yine text helper dosyasında bulunan character_limiter fonksiyonunu kullanabilirsiniz.