Pazartesi, 31 Ağustos 2009

Alışveriş Sepeti Uygulaması

 

Internet sayfalarında alışveriş sepeti uygulaması oldukça yaygın ve işe yarayan bir uygulamadır. Kullanıcı, ürün kataloğundan seçtiği ürünleri satın almadan önce bir sepete atar. Bu sepetteki ürünlerin sayısını satın almadan önce değiştirebildiği gibi sepetten çıkartabilir de. CodeIgniter yayımlanmasını beklediğimiz 1.7.2 sürümünde "Cart" isimli bir alışveriş sepeti kütüphanesini kendi dağıtım paketi içine almıştır.

Henüz resmi olarak dağıtıma sokulmamasına rağmen, kendi sitesinden edinebileceğimiz bu kütüphaneyi kullanarak bir alışveriş sepeti uygulamasının nasıl çalıştığını örnek uygulama ile anlatmaya çalışacağım.

Öncelikle buradaki CI_cart.php isimli dosyayı CI_Cart yazan yerlerini Cart olarak değiştirerek kendi kütüphanemiz gibi CodeIgniter uygulama paketimiz içine alıyoruz (bahsedilen düzeltimiş dosyayı, yazının sonundaki uygulama paketinde bulabilirsiniz). Bu dosyamızı application/libraries dizini altına cart.php ismi ile kayıt ediyoruz. Bu ayarlamaya CodeIgniter 1.7.2 paketinin yayımlanmasının ardından gerek kalmayacaktır.

Application/config dizini içinde autoload.php isimli dosyamızda açılışta otomatik yüklenmesi gereken kütüphaneler içinde "session" kütüphanesini ekliyoruz. Böylece Cart isimli kütüphanemiz için gerekli session kütüphanesini açılışta yüklemiş oluyoruz. Sonra sepet.php isimli bir controller dosyası yaratalım. Bu dosyamız yardımıyla alışveriş sepeti uygulamasını kontrol edelim. Sepet.php isimli dosyamızın yeri application/controllers dizini altındadır. İçeriği de aşağıdadır:

<?php

class Sepet extends Controller {

 function Sepet()
 {
  parent::Controller(); 
  $this->load->library('Cart');
  $this->load->helper('form');  
 }
 
 function index()
 {
 
  $data['urun_dizini'] = $this->_urun_dizini();
  $data['urun_listesi'] = $this->load->view('urun_view',$data,TRUE);
  $this->load->view('sepet_view',$data);
  
 }
 
 function yenile()
 {
  $update = array(
     'rowid' => $this->input->post('rowid'),
     'qty' => $this->input->post('qty')
    );
  
  $this->cart->update($update);

  $data['urun_dizini'] = $this->_urun_dizini();  
  $data['urun_listesi'] = $this->load->view('urun_view',$data,TRUE);
  $this->load->view('sepet_view',$data);
 }
 
 function ekle()
 {

  $urun_dizini = $this->_urun_dizini();
  $secilen_urun = $urun_dizini[$this->input->post('urun_id')];

  $this->cart->insert($secilen_urun);
  
  $data['urun_dizini'] = $this->_urun_dizini();     
  $data['urun_listesi'] = $this->load->view('urun_view',$data,TRUE);  
  $this->load->view('sepet_view',$data);
 }
 
 function temizle()
 {

  $this->cart->destroy();
 
  $data['urun_dizini'] = $this->_urun_dizini();   
  $data['urun_listesi'] = $this->load->view('urun_view',$data,TRUE);  
  $this->load->view('sepet_view',$data);
 }
 
 
 function _urun_dizini()
 {
 
  $return = array(
               '0' => array(
                       'id'      => 'sku_123ABC',
                       'qty'     => 1,
                       'price'   => 39.95,
                       'name'    => 'T-Shirt',
                       'options' => array('Size' => 'L', 'Color' => 'Red')
                    ),
               '1' => array(
                       'id'      => 'sku_567ZYX',
                       'qty'     => 1,
                       'price'   => 9.95,
                       'name'    => 'Coffee Mug'
                    ),
               '2' => array(
                       'id'      => 'sku_965QRS',
                       'qty'     => 1,
                       'price'   => 29.95,
                       'name'    => 'Shot Glass'
                    )
            );

  return $return;
 }
}


İçerikten takip edebileceğiniz gibi Cart isimli kütüphane ile form helper dosyasını index metodu altında yüklüyoruz. Böylelikle her farklı metodta tekrar yükleme derdinden kurtuluyoruz. İsterseniz autoload.php dasyası içine de ekleyebilirsiniz. Controller dosyamızda _urun_dizini isimli bir fonksiyon ile sitede sergileyeceğim ürünleri anlatımda kolaylık olsun diye bir diziye attım. Siz uygulama sırasında model dosyası aracılığıyla veritabanından ürün çekmeniz gereklidir.

Sepet.php isimli controller dosyamızda, "ekle" metoduyla sepete ürün eklenir, "yenile" metoduyla sepetteki ürünlerin sayısı değiştirilir ya da "0" değeri girilerek silinir, "temizle" metoduyla ise sepet boşaltılır. Bu işlemleri yapmak için cart kütüphanesindeki insert, update ve destroy isimli metodlarını kullandım. Eğer Cart isimli kütüphaneyi incelerseniz daha detaylı metodları olduğunu görebilirsiniz.

Ürünleri listelemek ve seçtirmek için urun_view.php isimli dosyayı kullanıyorum. Bu dosyanın yeri application/views dizini altındadır. İçeriği ise kendisine gelen $urun_listesi isimli diziyi ekrana bastırmaktır.


<table cellpadding="1" cellspacing="1" style="width:80%" border="1">

<tr>
  <th>Adet</th>
  <th>Ürün Tanımı</th>
  <th style="text-align:right">Birim Fiyatı</th>
  <th style="text-align:right">Opsiyon</th>
</tr>

<?php foreach($urun_dizini as $key=> $items): ?>

<?php echo form_open(base_url().'sepet/ekle'); ?>
 <?php echo form_hidden('urun_id', $key); ?> 
 <tr>
   <td><?php echo $items['qty']; ?></td>
   <td>
  <?php echo $items['name']; ?>
     
   <?php if (isset($items['options'])): ?>
     
    <p>
     <?php foreach ($items['options'] as $option_name => $option_value): ?>
      
      <strong><?php echo $option_name; ?>:</strong> <?php echo $option_value; ?><br />
          
     <?php endforeach; ?>
    </p>
    
   <?php endif; ?>
    
   </td>
   <td style="text-align:right"><?php echo $items['price']; ?></td>
   <td style="text-align:right"><?php echo form_submit('', 'Sepete Ekle'); ?></td>
 </tr>
<?=form_close()?> 
<?php endforeach; ?>

</table>



Sepet içindekileri listeleyen ve yenileme ile temizleme işlemi yapılmasına olanak veren view dosyası ise sepet_view.php, yeri ise application/views dizini altındadır.

<html>
<head>
<title>Alışveriş Sepeti Ornek</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
</head>

<body>

<?php if($urun_listesi) echo $urun_listesi;?>

<h1>Sepetinizin durumu</h1>

<table cellpadding="1" cellspacing="1" style="width:80%" border="1">

<tr>
  <th>Adet</th>
  <th>Ürün Tanımı</th>
  <th style="text-align:right">Birim Fiyatı</th>
  <th style="text-align:right">Ara Toplam</th>
  <th style="text-align:right">Opsiyon</th>
</tr>

<?php $i = 1; ?>

<?php foreach($this->cart->contents() as $items): ?>

<?php echo form_open(base_url().'sepet/yenile'); ?>
 <?php echo form_hidden('rowid', $items['rowid']); ?>
 
 <tr>
   <td><?php echo form_input(array('name' => 'qty', 'value' => $items['qty'], 'maxlength' => '3', 'size' => '5')); ?></td>
   <td>
  <?php echo $items['name']; ?>
     
   <?php if ($this->cart->has_options($items['rowid']) == TRUE): ?>
     
    <p>
     <?php foreach ($this->cart->product_options($items['rowid']) as $option_name => $option_value): ?>
      
      <strong><?php echo $option_name; ?>:</strong> <?php echo $option_value; ?><br />
          
     <?php endforeach; ?>
    </p>
    
   <?php endif; ?>
    
   </td>
   <td style="text-align:right"><?php echo $this->cart->format_number($items['price']); ?></td>
   <td style="text-align:right">$<?php echo $this->cart->format_number($items['subtotal']); ?></td>
   <td><p><?php echo form_submit('', 'Sepeti Yenile'); ?></p></td>
 </tr>
<?=form_close()?>
<?php $i++; ?>

<?php endforeach; ?>

<tr>
  <td colspan="2"> </td>
  <td class="right"><strong>Total</strong></td>
  <td class="right"><?php if($this->cart->total()) echo $this->cart->format_number($this->cart->total()); ?> usd</td>
</tr>

</table>
<?=form_close()?> 

<?php echo form_open(base_url().'sepet/temizle'); ?>
<p><?php echo form_submit('', 'Sepeti Boşalt'); ?></p>
<?=form_close()?> 

</body>
</html>

Her iki view dosyasını aynı anda görebilmek için controller dosyası içinde aşağıdaki mekanizmayı kurdum. Böylelikle urun_view.php dosyası içeriği alınarak sepet_view.php dosyası içine gönderilmektedir.

  $data['urun_dizini'] = $this->_urun_dizini();  
  $data['urun_listesi'] = $this->load->view('urun_view',$data,TRUE);
  $this->load->view('sepet_view',$data);

Ana hatlarıyla yukarıda anlattığım alışveirş sepeti uygulaması CodeIgniter 1.7.2. sürümüyle birlikte aktif hale gelecektir. Yeni sürümü beklemeden kullanacaklar için hazırladığım bu uygulamayı CI_sepet.zip isimli dosya ile indirerek kullanabilirsiniz.

@04.10.2009 - Yenileme: CodeIgniter 1.7.2 ile birlikte dağıtım paketine alınan cart kütüphanesi ve yukarıdaki kodlar ile çalışır hale getirdiğim bu uygulamanın demo örneği için şu adresi kullanabilirsiniz : Alışveriş Sepeti Demosu

Yorumlar

Sağolun Fatih bey bende 2 gün önce görmüştüm denedim baya ilerletmiş ci sistemi :) şuanlık betada ama nerdeyse bitmiş gibi cart sistemi

Emeğine sağlık dostum yine güzel bir yazı

Çok teşekkürler fatih bey gerçekten çok hızlısınız :)

eline sağlık fatih ci yakında herşeyi paket yapacak böyle gidersede bize gerek kalmaz herhalde :D ci indir kur :===)))))

CodeIgniter 1.7.2 versiyonundan sonra dağıtım paketine giren bu kütüphaneyi kullanırken CI_Cart.php isimli dosyaya artık gerek yok. CodeIgniter paketi içinden Cart kütüphanesi çıktığı için o dosyaya ihtiyacınız kalmadı.

Bir de ürünlerin isimlerinde Türkçe karakterler kullanılırsa sorun çıktığı bildirildi. Bunu çözmek için ise system/libraries dizini altındaki Cart.php dosyasına girerek $product_name_rules isimli değişkeni şöyle düzeltin:

var $product_name_rules	= '\.\:\-_ a-üöçşığz A-ÜÖÇŞİĞZ 0-9';

CodeIgniter yeni versiyonuyla beni hayal kırıklığına uğrattı. CI bir frameworkmü yoksa CMS'mi ne alaka bu cart classı anlamadım sanki diğer herşey güllük gülistanlıktı. CI core içinde template classı yok, özellikle caching konusunda CI bir rezalet sunuyor. Bunları bırakmışlarda cart class'ıyla uğraşıyorlarsa bu frameworkün geleceğini hayırlı görmüyorum.

Eskiden CI içinde smarty kullanılmasını çok saçma buluyordum ama CI'nin rezil cachinginin zayıflığını ancak smarty örtüyor. CI'nin yeni versyionlarında daha iyileşeceğine olan inancımı kaybettirdi bu cart class'ı CI'yi seçmek için çok sebep var ama seçmemek içinde bir o kadar var. Bu class'tan sonra diğer frameworkler arasından bir seçim yapmak arifesindeyim.

@Metehan: CodeIgniter, yeni versiyonunda caching kütüphanesini değiştireceğinden zaten bahsetmemişti.

CodeIgniter caching kütüphanesi basit ve hızlı çalışan bir kütüphanedir.Eğer sorunun üye olanlara ve olmayanlara farklı gösterimler yapmaksa Sparks isimli kütüphane işini görebilir. Sorunun sayfaların hızlı açılması ise burada anlattığım teknik caching kütüphanesiyle de sorunsuz çalışmaktadır.

Daha gelişmiş bir caching kütüphanesi istersen yazmak senin elinde.

@Fatih bey: Açıkçası gelecek versiyonlarda ne gelip gelmeyeceğini takip etmiyorum o yüzden cart class'ını görünce baya şaşırdım.

Sorunum üye olanlara farklı şeyler göstermekte değil açıkçası teorik olarak öyle demiştim kendi auth library'im ile çok kolayca hallediyorum onları zaten. Tabiki gelişmiş bir caching kütüphanesi de yazabilirim ihtiyaca göre ama işte framework kullanıyoruz cachingi bile biz yazacaksak ellis lab ne işe yarayacak sadece teorik olarak eleştirmiştim.

Aslında smarty'den rahatsızda değilim o kadar çok sevdimki dünyanın en iyi cachingini yazsalar ci'ye artık smarty'i bırakacağımı düşünüyorum :)

Kusura bakmayın blog'unuzu da foruma çevirdim :) iyi çalışmalar.

Yorum Ekle