Jump to content

Ajax Puanlama Uygulaması


Recommended Posts

Dosyalar

İlk olarak betiğimizde kullanacağımız dosya/dizin yapısını ve neler yapacağımızı görelim. Ana dizin içeriğini Resim 1’de ve resimler klasörünün içeriğini Resim 2’de görebilirsiniz.

oylama-resim1.jpg

oylama-resim2.jpg

Ana dizinde yer alan dosyalardan index.php, ana sayfamız oluyor. Temel işlemlerimiz bu sayfada olacak. Prototype.js, AJAX fonksiyonları ve başkaca yararlı fonksiyonları içeren JavaScript kütüphanemiz. Baglan.php, veritabanımız ile bağlantıyı sağlayan dosyamız. Oyver.php, kullanıcı oy verdiği zaman bunu veritabanına kaydeden dosya. Oyal.php ise ilgili yazının aldığı oyların durumunu ekranda görüntüleyen dosya. Resimler klasöründe de kullanacağımız ya da kullanmayacağımız bazı renkte yıldız resimleri bulunuyor. Yazının sonundaki bağlantılar aracılığıyla bu resimleri indirdiğinizde kendi uygulamalarınız için istediğiniz rengi kullanabilme şansına sahip olacaksınız.

Neler Yapacağız ?

• Öncelikle ana sayfamız olan index.php dosyasının genel şablonunu oluşturacağız. Bu sayfaya çok temel düzeyde bir makale sistemi koyacağız. Bu, örnek bir uygulama olduğundan ve göstermek istediğim asıl şey puanlama mekanizması olduğundan, diğer unsurlara pek önem vermiyorum. Bu yüzden çok basitçe yazdım. Siz kendi uygulamalarınızda geliştirebilirsiniz.

• Oyal.php adlı dosyamızı yazacağız. Bu dosya veritabanındaki puanların ana sayfamızda görüntülenmesini sağlıyor.

• Oyver.php adlı dosyamızı yazacağız. Bu dosya da kullanıcı oy verdiğinde puanların veritabanına yazılmasını sağlıyor.

• Son olarak index.php adlı ana sayfamıza dönerek Ajax ile ilgili kısımları tamamlayacağız ve puan verme sistemimiz tamamlanmış olacak.

Siz de bu yazıyla birlikte bu sistemi kodlayacaksanız, öncelikle hazır olarak kopyalanması gereken dosyaları yazının sonunda bularak ana klasörünüze kopyalayın. Bunlar; resimler klasörü ve içindeki dosyalar, prototype.js dosyası ve baglan.php dosyasıdır. Baglan.php dosyasını kendi veritabanı bilgilerinize göre değiştirmelisiniz tabii. Bu arada veritabanımızda da yazilar ve puanlar isminde iki tablo bulunuyor. Bu tabloların yapısını aşağıdaki resimlerde bulabilirsiniz. Tablo yapısı ve örnek verilere ait SQL sorgularını da yazının sonunda bulabilirsiniz.

oylama-resim3.jpg

oylama-resim4.jpg

Ana Sayfa

index.php’nin genel yapısı aşağıdaki gibi olacak.

<?php
include "baglan.php";
?>
<html>
<head>
<title>Puan Verme Örneği</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-9" />
<script type="text/javascript" src="prototype.js"></script>
</head>
<body>
<?php
if($_GET['id']) {
$sql = "SELECT * FROM yazilar WHERE id = '" . $_GET['id'] . "'";
$sorgu = mysql_query($sql);
$sonuc = mysql_result($sorgu, 0, "metin");
echo "<p>" . $sonuc . "</p>";
?>
<div id="oylama"></div>
<?php
} else {
$sql = "SELECT * FROM yazilar ORDER BY id DESC";
$sorgu = mysql_query($sql);
while($sonuc = mysql_fetch_array($sorgu)) {
echo "<a href=\"index.php?id=" . $sonuc['id'] . "\">";
echo $sonuc['baslik'] . "</a><br />";
}
}
?>
</body>
</html>[/CODE]

Şablon kodumuzda açıklayacak pek birşey yok aslında. Sayfamızda veritabanı işlemleri yapacağımız için baglan.php dosyasını en başta include ediyoruz. Ayrıca prototype.js dosyamızı da sayfamıza dahil etmeyi unutmuyoruz. Daha sonra eğer $_GET[‘id’] diye bir değişken yoksa mevcut tüm yazıları listeleyen, bunların herhangi birine tıklayınca da $_GET[‘id’] değişkeni oluşacağı için ilgili yazıyı gösteren kodu yazıyoruz. Alta da puanın gösterileceği oylama div’ini yerleştiriyoruz.

[color=#FF0000]Oyal.php[/color]

[CODE]<?php

include "baglan.php";

$id = $_POST['id'];
$ip = getenv("REMOTE_ADDR");

$sql = "SELECT * FROM puanlar WHERE yazi = '" . $id . "'";
$sorgu = mysql_query($sql);
$say = mysql_num_rows($sorgu);
$puan = 0;
while($sonuc = mysql_fetch_array($sorgu)) {
$puan += $sonuc['puan'];
}
$ort = @($puan / $say);
$ortalama1 = sprintf("%01.2f", $ort);
$ortalama2 = round($ort);
$bos2 = 5 - $ortalama2;

$sql_ = "SELECT * FROM puanlar ";
$sql_ .= "WHERE yazi = '" . $id . "' AND veren = '" . $ip . "'";
$sorgu_ = mysql_query($sql_);
$say_ = mysql_num_rows($sorgu_);
if($say_ == 1) {
$puan_ = mysql_result($sorgu_, 0, "puan");
$bos_ = 5 - $puan_;
for($i = 1; $i <= $puan_; $i++) {
echo "<img src=\"resimler/mavi.gif\" />";
}
for($j = 1; $j <= $bos_; $j++) {
echo "<img src=\"resimler/gri.gif\" />";
}
} else {
for($i = 1; $i <= $ortalama2; $i++) {
echo "<img class=\"yildiz\" id=\"r" . $i;
echo "\" src=\"resimler/sari.gif\" onmouseover=\"omo(" . $i;
echo ");\" onmouseout=\"omout();\" onclick=\"oc(" . $i;
echo ");\" />";
}
for($j = 1; $j <= $bos2; $j++) {
echo "<img class=\"yildiz\" id=\"r" . ($ortalama2 + $j);
echo "\" src=\"resimler/gri.gif\" onmouseover=\"omo(";
echo ($ortalama2 + $j) . ");\" onmouseout=\"omout();\" ";
echo "onclick= \"oc(" . ($ortalama2 + $j) . ");\" />";
}
}

echo " [Ortalama puan <b>" . $ortalama1;
echo "</b>, puanlayan kişi sayısı <b>" . $say . "</b>]";

?>[/CODE]

Sayfanın başına veritabanına bağlantımızı içeren baglan.php dosyasını include ediyoruz. Puan bilgisi alınacak yazının id’sini ve kullanıcının IP adresini ilgili değişkenlere atıyoruz.

Burada IP adresini nerede kullanacağımızla ilgili bilgi vermek istiyorum. Ben bu sistemi kodlarken bir ziyaretçinin birden fazla oy verememesi için ziyaretçinin IP adresini kayıt etme yoluna başvurdum. Aslında amacım temel mantığı göstermek olduğu için ayrıntılara pek takılmadığımı daha önce de söylemiştim. Bu yüzden bir ziyaretçinin birden fazla oy verememesini tamamen böyle bir sistemle sağlamak doğru olmaz. Cookie ve Session gibi başkaca sistemler de kullanmak ve veritabanına da çok fazla yük getirmememesi açısından bir süre sonra kayıtları temizlemek gibi ekstralarla bu sistemi geliştirmek mümkün ve hatta gerekli. Ama yine de kodları çok fazla karıştırmamak açısından ben bu sistemle kodlayacağım.

Değişkenleri atadıktan sonra veritabanından o yazıya verilen toplam puanı puan değişkenine, ortalama puanı da ort değişkenine yazdırıyoruz. Ort değişkenindeki @ işareti; eğer say değişkeni 0 ise, yani o yazıya daha önce kimse puan vermemişse Division by zero yani Sıfırla bölünme hatası vermesini önlemek için konmuştur. Ortalama1 değişkeni ort değişkeninin 2 ondalık hanesi bulunan, ortalama2 değişkeni ise ort değişkeninin hiç ondalık hanesi bulunmayan, yani tamsayı olan halidir. Ortalama2 değişkeni aynı zamanda sarı olan yıldızların sayısı olacağı için bos2 değişkeni ise geriye kalan gri yıldızların sayısı olacaktır.

Bundan sonra bir kontrol yapmamız gerekiyor. Bu kullanıcı aynı yazıya daha önce puan vermiş mi ? Bu kontrolü yapmak için bir sorgumuz ve onu izleyen bir if kalıbımız var. Eğer kullanıcı yazıya daha önce de puan verdiyse; yazıya verilen ortalama puan değil de, yazıya kullanıcının verdiği puan gösterilecek. Ortalama puan ise ifade olarak yer alacak. Kullanıcıya gösterilen yıldızlar ise sarı değil mavi olacak. Eğer kullanıcı ilgili yazıya daha önce puan vermemişse, bu sefer gösterilen yıldızlar sarı olacak, onmouseover durumunda omo(x) adlı JavaScript fonksiyonu çalıştırılacak. Bu fonksiyonda x, o yıldızın kaçıncı yıldız olduğunun numarası oluyor. Yani örneğin 3. yıldızsa, omo(3) fonksiyonu çalıştırılacak ve bu fonksiyonun görevi 3. yıldıza kadar olan tüm yıldızları mavi, diğer yıldızları ise gri yapmak olacak. Onmouseout durumunda, tüm yıldızların eski haline dönmesini sağlayan, parametresiz omout() fonksiyonu çalıştırılacak. Onclick durumunda ise oc(x) fonksiyonu çalıştırılarak kullanıcının yazıya x puan vermesi sağlanacak.

En sona da her durumda yazının ortalama ne kadar puan aldığı ve kaç kişinin puanlamaya katıldığı bilgisi yazılıyor.

oylama-resim5.jpg

oylama-resim6.jpg

[color=#FF0000]Oyver.php[/color]

[CODE]<?php

include "baglan.php";

$id = $_POST['id'];
$puan = $_POST['puan'];
$puan = @round($puan);
$veren = getenv("REMOTE_ADDR");

$sql = "SELECT * FROM puanlar WHERE yazi = '" . $id . "' AND veren = '";
$sql .= $veren . "'";
$sorgu = mysql_query($sql);
$say = mysql_num_rows($sorgu);
if($say == 0) {
$sql = "INSERT INTO puanlar (yazi, puan, veren) VALUES('" . $id;
$sql .= "', '" . $puan . "', '" . $veren . "');";
mysql_query($sql);
}

?>[/CODE]

Bu dosya ise puanların veritabanına yazılma işlemini gerçekleştiriyor. Öncelikle baglan.php ile veritabanı bağlantısı sağlandıktan sonra puan verilen yazının id’si, verilen puan, ve puan verenin IP adresi ilgili değişkenlere yazılıyor. Daha sonra ise, eğer puan veren kişi daha önce de aynı yazıya puan vermemişse, puan verme işlemi tamamlanarak veritabanına yazılıyor. Bu dosya sadece bir işlem yapan bir dosya, geri döndürdüğü bir değer yok.

Ana Sayfanın Ajax ile İlgili Kısımları

Ana sayfada prototype.js’yi dahil ettikten sonraki kısma şu JavaScript fonksiyonlarını ekliyoruz.

[CODE]<script type="text/javascript">
Event.observe(window, 'load', oyal, false);
var dizi = new Array();

function oyal() {
$('oylama').innerHTML = 'Oy alınıyor ...';
var sc = 'id=<?php echo $_GET['id']; ?>';
var nesne = new Ajax.Updater('oylama', 'oyal.php', {method: 'post', parameters: sc});
}

function omo(kac) {
for(i = 1; i <= kac; i++) {
dizi[i] = $('r' + i).src;
$('r' + i).src = 'resimler/mavi.gif';
}
var bos = 5 - kac;
for(j = 1; j <= bos; j++) {
t = kac + j;
dizi[t] = $('r' + t).src;
$('r' + t).src = 'resimler/gri.gif';
}
}

function omout() {
for(i = 1; i <= 5; i++) {
$('r' + i).src = dizi[i];
}
}

function oc(kac) {
$('oylama').innerHTML = 'Oy gönderiliyor ...';
var sc = 'id=<?php echo $_GET['id']; ?>&puan=' + kac;
var nesne = new Ajax.Request('oyver.php', {method: 'post', parameters: sc, asynchronous: false});
oyal();
}
</script>[/CODE]

Event.observe(window, 'load', oyal, false); satırı, prototype.js’nin bize yaptığı bir güzellik ve sayfa yüklenir yüklenmez oyal() fonksiyonunun çalıştırılmasını sağlıyor.

[color=#0000FF]Oyal()[/color] fonksiyonu öncelikle div’imize Yükleniyor tarzında bir yazı yazdırıyor. Daha sonra puanı alınacak yazının id’sini gönderilmek üzere sc değişkenine yazdırıyor. Bir sonraki satırda ise oyal.php dosyasına sc değişkeni parametreleri içerecek şekilde post metoduyla gönderilirken, sonuçlar da oylama adlı div’e yazdırılıyor.

[color=#0000FF]Omo(kac)[/color] fonksiyonu ise belirtilen yıldıza kadar olan yıldızların hepsinin mavi renge, diğerlerinin ise gri renge dönüşmesini sağlıyor. Bunu yaparken de yıldızların ilk hallerini dizi adlı dizi değişkene aktarıyor.

[color=#0000FF]Omout()[/color] fonksiyonu yıldızların hepsinin ilk hallerine dönmesini sağlıyor. Bunu dizi adlı değişkeni kullanarak yapıyor.

Oc(kac) fonksiyonu ise istenen puanın yazıya verilmesini sağlıyor. Öncelikle ekrana Yükleniyor tarzında bir yazı yazdıktan sonra, sc değişkenine, gönderilecek parametreleri yazıyor. Bu parametreler yazının id’si ve verilen puan oluyor. Daha sonra oyver.php dosyasına bu parametreler gönderilerek puanın verilmesi sağlanıyor ve en son olarak da puanlar güncellenmiş haliyle oyal() fonksiyonu ile ekrana yazdırılmış oluyor.

Bu son fonksiyonda aklınıza takılmış olduğunu düşündüğüm iki soruyu cevaplayayım. Birincisi neden Ajax.Updater değil de Ajax.Request kullandığımızı sorabilirsiniz. Bunun sebebi dosyanın geri bir değer döndürmemesidir. Dosya sadece işlemimizi yapmış olur böylece. İkinci mevzu ise niye asynchronous: false ifadesini kullandığımızı sorabilirsiniz. Ben yaptığım denemelerde bazen oyal() fonksiyonuyla alınan puanların içinde bir adım önce verilen puanların hesaba katılmayabildiğini gördüm. İki işlem arasında çok kısa bir zaman aralığı olduğundan, bir işlem tamamlanmadan diğerinin tamamlanması yanlış sonuçlara neden olabiliyordu. Bu yüzden bir işlemin başlaması için diğer işlemin tamamlanmasını bekleme olayını sağlamış oldum.

Yıldızların üzerine gelindiğinde farenin el şekline dönüşmesi için de yine head bölümüne şu kodu ekleyebiliriz :

[CODE]<style type="text/css">
img.yildiz { cursor: pointer; }
</style>[/CODE]

Tüm bunlardan sonra puanlama sistemimizi tamamlamış oluyoruz. Denemelerimizi yapıp emeğimizin ürününü almak gerçekten keyifli ... Böylece bundan sonraki uygulamalarımızda bu sistemi kullanabiliriz. Hayırlı olsun ! 

Tabii daha önce de belirttiğim gibi benim bu yazıyı yazarken asıl amacım sistemin temel mantığının nasıl olduğunu göstermek olduğundan birçok ayrıntıyı es geçmek durumunda kaldım. Bu ayrıntılar da tamamlanarak başkaca özellikler de eklenirse kusursuz uygulamalara imza atılabilir.

Yazıyı elimden geldiğince anlaşılır yazmaya özen gösterdim. Anlaşılmayan yerler varsa (iletisim [at] gokhanozturk [nokta] com [nokta] tr) e-posta adresimi kullanarak bana soru sorabilirsiniz. Bundan sonra da başkaca konularda makale yazmak isterim. Umarım siz Ajax-Tr ziyaretçilerine yararlı olabilirim.

İNDİR

___________________________

http://www.yakuter.com/puanlama/puanlama.rar

Gökhan ÖZTÜRK (fonemi)

[/left]

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...