28 September 2013

Ajax Counter Sederhana dengan PHP

Pembaca yang budiman, pernahkah kita melihat sebuah status di media sosial seperti facebook, twitter, atau media sosial lain yang status tersebut memiliki attribut like, share, atau yang lainnya. Mekanisme tersebut merupakan mekanisme counter (penghitungan). Lantas kemudian data penghitungannya tersebut bisa disimpan dimana saja, bisa di database, di file atau media penyimpanan lain.
Untuk materi kali ini, kita akan mencoba membuat sebuah counter sederhana sesuai dengan inspirasi diatas, tentu saja dengan mekanisme ajax yang bekerja dibelakang halaman url sehingga user tidak merasa ada pergantian halaman. Dan kita akan mencoba membuatnya dengan menggunakan php sebagai script pemrogramannya. Sehingga hasilnya nanti akan seperti gambar dibawah ini:

Mari kita mulai percobaan kita ini.
Data - Data yang kita gunakan sebagai sumber data dalam percobaan kali ini adalah:
  1. Data - data status yang berupa flat text file. Oleh karena kali ini fokus utama kita adalah ajax counter-nya, maka sumber data untuk statusnya kita persiapkan dalam flat file text saja. Dalam pengembangannya nanti kita bisa menggunakan mekanisme database untuk data-data status ini sesuai dengan keinginan kita. Kita akan mempersiapkan dua file status saja sebagai sumber data seperti gambar diatas.
  2. Data - data counter per-status. Data-data counter tiap-tiap status juga disimpan dalam flat file txt dengan nama yang sama dengan nama file status tersebut tapi diletakkan dalam directory yang berbeda.
Sementara script-script yang bisa kita siapkan adalah sebagai berikut:
Untuk percobaan ini kita menggunakan dua buah script PHP yaitu ClassPhpVoter.php dan vote_tools.php. Dan dua scripts ini kita letakkan dalam satu directory yang sama.
Adapun isi file ClassPhpVoter adalah seperti berikut ini:
<?php
/**
 *----------------------------------------------------------------------------------------------------------------------
 *
 * Created by JetBrains PhpStorm.
 * User: Josescalia
 * Date: 9/28/13
 * Time: 12:08 PM
 *----------------------------------------------------------------------------------------------------------------------
 */
class PhpVoter {

    function readVote($file) {
        if(file_exists($file)){
            $handle = fopen($file, 'r+');
            $countVote = fread($handle, 512);
            fclose($handle);
            return $countVote;
        }else{
            //if file not exist create one and retun the process from beginning
            $handle = fopen($file, 'w');
            fwrite($handle, 0);
            fclose($handle);
            return $this->readVote($file);
        }
    }

    /*
     * This function should always called before the readVote call first
     * */
    function doVote($file){
        if(file_exists($file)){
            $handle = fopen($file, 'r+');
        }
        $countVote = fread($handle, 512);
        fseek($handle, 0);
        fwrite($handle, $countVote+1);
        fclose($handle);
    }
}

Pada script diatas kita bisa melihat ada dua buah fungsi yang terdapat pada class PhpVoter tersebut, yaitu fungsi untuk membaca hasil vote (function readVote($file)) dan fungsi untuk menulis/menambahkan vote (function doVote($file)), silahkan anda telaah sendiri isi dari logika ke dua fungsi tersebut.
Isi dari file kedua (vote_tools.php) adalah seperti dibawah ini:
<?php
/**
 *-------------------------------------------------------------------------------------------
 *
 * Created by JetBrains PhpStorm.
 * User: Josescalia
 * Date: 9/28/13
 * Time: 12:08 PM
 *-------------------------------------------------------------------------------------------
 */
require "ClassPhpVoter.php";
$voteTools = new PhpVoter();

$file = $_GET['file_to_read'];
$actType = $_GET['act'];
if ($actType == "write") {
    $voteTools->doVote("../counter-data-source/" . $file);
}

echo "" . $voteTools->readVote("../counter-data-source/" . $file) . " people like this";
?>
File diatas merupakan file yang nantinya akan menjadi trigger aplikasi kita ini. Adapun secara detail isi dari file tersebut bisa dideskripsikan seperti ini. Jika parameter actType sama dengan "writer" maka fungsi doVote yang ada pada file ClassPhpVoter.php akan dieksekusi, dan kemudian fungsi readVote akan di eksekusi setelahnya untuk menampilkan jumlah total vote yang tersimpan dalam file data counter.

Kemudian kita juga mempersiapkan script html. Script html ini merupakan script sebagai container sebagai bentuk tetap aplikasi diatas dengan layout yang sudah kita tentukan sebelumnya seperti pada gambar diatas.

Berdasarkan screenshot layout gambar diatas maka dibawah ini adalah script html tersebut:
<body>
<div class="main">
    <h4>Simple Ajax Counter</h4>
    <div class="outer-status">
        <div id="cmnt_01" class="status">
        </div>
        <div class="outer-status-like">
            <img src='images/icon-fb-like-s.png' height='16px' width='16px'>

            <div class="like_counter"></div>
            <div class="like_tools">
                <a href="#" class="btnLike" title="status_1.txt">Like</a>
            </div>
        </div>
    </div>
    <div class="outer-status">
        <div id="cmnt_02" class="status">
        </div>
        <div class="outer-status-like">
            <img src='images/icon-fb-like-s.png' height='16px' width='16px'>
            <div class="like_counter"></div>
            <div class="like_tools"><a href="#" class="btnLike" title="status_2.txt">Like</a></div>
        </div>
    </div>
</div>
</body>
Dan untuk styling-nya berikut ini script css yang bisa diterapkan pada design layout tersebut:
body {font-family: verdana, tahoma, sans-serif; font-size: 14px;}

.main { margin: 0 auto; width: 500px; border: 1px solid #add8e6; padding-bottom:30px;}

.main h4{text-align: center;font-variant: small-caps;}

.outer-status { margin: 10px auto; width: 350px; border: 1px solid #add8e6;}

.status {padding: 5px;}

.outer-status-like {font-size: 12px;height: 24px; border-top: 1px solid #add8e6;background-color: rgba(202, 226, 252, 0.45);}

.outer-status-like img {margin: 3px 5px 2px 5px; float: left;}

.like_tools {float: right;margin: 3px 5px 2px 0;}

.like_counter {float: left;margin: 3px 5px 2px 0;}

Script selanjutnya yang kita persiapkan adalah javascript. Javascript kita persiapkan sebagai elemen yang paling penting yang berfungsi menyatukan semua yang sudah kita buat diatas, sebab percobaan kita kali ini menggunakan metode ajax dalam mekanisme pengambilan datanya. Disini kita menggunakan JQuery sebagai framework javascript dengan tujuan agar pembuatan mekanisme ajax menjadi lebih mudah. Berikut code-code javascript-nya:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            //------------ambil semua data status dan attribut like-nya--------------------------//
            $.get("status-data-source/status_1.txt", function (data) {
                $("#cmnt_01").html(data);
                $.get("scripts/vote_tools.php?act=read&file_to_read=status_1.txt", function (likeData) {
                    $("#cmnt_01").next(".outer-status-like").children(".like_counter").append(likeData)
                });
            });


            $.get("status-data-source/status_2.txt", function (data) {
                $("#cmnt_02").html(data);
                $.get("scripts/vote_tools.php?act=read&file_to_read=status_2.txt", function (likeData) {
                    $("#cmnt_02").next(".outer-status-like").children(".like_counter").append(likeData)
                });
            });

            //-----------------------------------------------------------------------------------//

            //lakukan penghitungan jika user mengklik tombol suka dan ambil hasil penghitungan dengan
            // ajax
            $(".btnLike").click(function(){
                var fileToVote = $(this).attr("title");
                var elToSync = $(this).parent(".like_tools").prev();  //cursor mundur ke parent dan sebelumnya
                $.get("scripts/vote_tools.php?act=write&file_to_read="+fileToVote+"", function (likeData) {
                    $(elToSync).html(likeData);
                });
            });

        });
</script>

Javascript diatas bisa dibuat terpisah dengan sebuah file javascript tersendiri, namun bisa juga kita letakkan di dalam file index.html. Untuk percobaan ini kita akan menyatukannya javascript di atas ke dalam file index.html.

Setelah semua yang kita perlukan terkumpul, struktur direktori pada aplikasi ini seharusnya akan terlihat seperti gambar dibawah ini:

Alur Aplikasi
Dengan gambar tersebut kita bisa melihat flow yang terjadi adalah sebagai berikut. Ketika halaman di muat pertama kali, halaman akan memanggil status-status yang ada beserta atribut orang yang menyukainya dan menempatkannya ke dalam div dengan class outer-status. Dimana untuk isi statusnya kita letakkan ke dalam div dengan class status, dan untuk counter like-nya kita letakkan dalam div dengan class like_counter. Kita bisa melakukan ini dengan menggunakan mekanisme ajax get seperti pada tutorial ini.
Dan ketika user mengklik tombol Like pada tiap-tiap status yang ada maka tombol tersebut akan men-trigger script penghitungan untuk menambahkan jumlah like dan kemudian meng-invoke kembali dengan cara membaca jumlah status tersebut dan menampilkannya kembali ke dalam div dengan class like_counter. Semua cara ini akan kita lakukan melalui mekanisme ajax sehingga user tidak akan merasakan pergantian halaman ketika mereka mengklik tombol Like tersebut.
Demikianlah percobaan kita kali ini, silahkan dikembangkan untuk penggunaan yang lebih luas dan lebih bervariasi. Seluruh source-code untuk percobaan ini bisa di download dari sini

Semoga bermanfaat.

Josescalia

No comments: