349
IMPLEMENTASI SISTEM PAKAR MENGGUNAKAN METODE DEMSTER SHAFER UNTUK MENDETEKSI PENYAKIT GIGI SKRIPSI untuk memenuhi sebagian persyaratan mencapai derajat Sarjana S1 pada jurusan Teknik Informatika Oleh: UNI WAHYUNI 311610792 TEKNIK INFORMATIKA SEKOLAH TINGGI TEKNOLOGI PELITA BANGSA BEKASI 2018

untuk memenuhi sebagian persyaratan mencapai derajat

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: untuk memenuhi sebagian persyaratan mencapai derajat

IMPLEMENTASI SISTEM PAKAR MENGGUNAKAN

METODE DEMSTER SHAFER UNTUK

MENDETEKSI PENYAKIT GIGI

SKRIPSI

untuk memenuhi sebagian persyaratan mencapai

derajat Sarjana S1 pada jurusan Teknik Informatika

Oleh:

UNI WAHYUNI

311610792

TEKNIK INFORMATIKA

SEKOLAH TINGGI TEKNOLOGI PELITA BANGSA

BEKASI

2018

Page 2: untuk memenuhi sebagian persyaratan mencapai derajat

MOTTO

“Remember Me, I will remember you”

(QS: Al-Baqarah : 152)

“Melangkahlah, Allah akan berikan jalan. Semua karena Allah”

(Triningsih)

“Hajar. Jangan takut gagal”

(Edi Santoso)

“Jangan takut. Takutlah hanya kepada Allah SWT”

(Penulis)

Page 3: untuk memenuhi sebagian persyaratan mencapai derajat

PERSEMBAHAN

Segala puji Syukur atas berkah dan rahmat dari Allah Subhanalllah Wata’ala,

Kupersembahkan Skripsi Ini Untuk Orang-Orang Yang Selalu Kuharapkan

Cinta dan Kasih Sayangnya…

Teruntuk Ibu dan Ayah yang tidak pernah memutus doa untuk anakanaknya,

terimakasih untuk menopang jatuhku dan menuntunku, terimakasih

untuk jadi saksi langkah-langkahku…

Teruntuk adikku, terima kasih untuk dukungan dan doanya…

Teruntuk teman-temanku tercinta, terimakasih untuk selalu ada menunggu dan menemani…

Almamater Tercinta,

Kampus STT Pelita Bangsa

Page 4: untuk memenuhi sebagian persyaratan mencapai derajat
Page 5: untuk memenuhi sebagian persyaratan mencapai derajat
Page 6: untuk memenuhi sebagian persyaratan mencapai derajat

iii

Abstraksi

Sistem pakar merupakan sebuah sistem penyelesaian masalah dengan

menuangkan pengetahuan manusia ke dalam sebuah sistem seperti yang biasa di

lakukan oleh para ahli. Sistem pakar memudahkan manusia untuk menyelesaikan

masalah yang biasanya dilakukan oleh para ahli walaupun hanya dilakukan oleh

orang yang awam. Sistem pakar juga dapat membantu tugas para ahli atau sebagai

asisten yang dapat diandalkan untuk menangani masalah tanpa harus konsultasi

langsung dengan para ahli. Penelitian ini bertujuan untuk mengembangkan sistem

pakar diagnosa penyakit gigi menggunakan algoritma Dempster Shafer untuk

mendiagnosa penyakit gigi berdasarkan presentasi terbesar dari gejala yang

dialami. Sistem pakar ini diimplementasikan pada komputer menggunakan bahasa

pemrograman berbasis Website dengan menggunakan PHP dan database MySQL.

Hasil dari sistem pakar ini diharapkan dapat memudahkan pengguna dalam

melakukan konsultasi dan pengguna mendapatkan hasil diagnosa yang akurat

tentang penyakit gigi yang dialami serta penanganan yang tepat menggunakan

algoritma Dempster Shafer.

Kata Kunci : Sistem pakar, Penyakit gigi, Dempster Shafer

Page 7: untuk memenuhi sebagian persyaratan mencapai derajat

iv

Abstraction

Expert system is one of the problem solving system with pour out human

scientific knowledge into a system which usually done by the expert. Expert

system make common people being feel easier to do and finish their tasks, even

though usually the expert who finish and complete the problem.

Expert system also can help the expert job task or as an assistant which can count

on to handle the problem without direct discuss with the expert. This research’s

purpose is to develop the expert system for dental disease diagnose by using the

“Dempter Shafer” to diagnose dental disease based on biggest presentation from

the symptom. This expert system is implemented to the computer using website

programmer language with PHP and database MySQL.

The result from this expert system are expected can make the user feel easier to do

the consulting and get accurate result diagnose about the suffer dental disease and

also the proper handling use the algoritma dempster Shafer

Kata Kunci : Sistem pakar, Penyakit gigi, Dempster Shafer

Page 8: untuk memenuhi sebagian persyaratan mencapai derajat
Page 9: untuk memenuhi sebagian persyaratan mencapai derajat

vi

KATA PENGANTAR

Puji syukur penulis panjatkan ke hadiran Allah SWT. yang telah

melimpahkan segala rahmat dan hidayah-Nya, sehingga tersusunlah Skripsi yang

berjudul IMPLEMENTASI SISTEM PAKAR MENGGUNAKAN METODE

DEMPSTER SHAFER UNTUK MENDETEKSI PENYAKIT GIGI”.

Skripsi tersusun dalam rangka melengkapi salah satu persyaratan dalam

rangka menempuh ujian akhir untuk memperoleh gelar Sarjana Komputer

(S.Kom.) pada Program Studi Teknik Informatika di Sekolah Tinggi Teknologi

Pelita Bangsa.

Penulis sungguh sangat menyadari, bahwa penulisan Skripsi ini tidak akan

terwujud tanpa adanya dukungan dan bantuan dari berbagai pihak. Sudah

selayaknya, dalam kesempatan ini penulis menghaturkan penghargaan dan ucapan

terima kasih yang sebesar-besarnya kepada:

a. Bapak Dr. Ir. Suprianto, M.P selaku Ketua STT Pelita Bangsa

b. Bapak Aswan Supriyadi Sunge, S, M.Kom selaku Ketua Program Studi

Teknik Informatika STT Pelita Bangsa.

c. Bapak Muhammad Fatchan, S.Kom, M.Kom selaku Pembimbing 1 (satu)

yang telah banyak memberikan arahan dan bimbingan kepada penulis

dalam penyusunan Skripsi ini.

d. Bapak Ikhsan Romli, S. Si, M.Sc, selaku Pembimbing 2 (dua) yang telah

meluangkan waktunya dalam penyelesaiaan skripsi sampai selesai, terima

kasih sudah memberikan arahan dan sudah memotivasi saya dalam

penyusunan skripsi ini.

e. Seluruh Dosen STT Pelita Bangsa yang telah membekali penulis dengan

wawasan dan ilmu di bidang teknik informatika.

f. Seluruh staf STT Pelita Bangsa yang telah memberikan pelayanan terbaiknya

kepada penulis selama perjalanan studi jenjang Strata 1.

g. Rekan-rekan mahasiswa STT Pelita Bangsa, khususnya angkatan 2018, yang

telah banyak memberikan inspirasi dan semangat kepada penulis untuk dapat

menyelesaikan studi jenjang Strata 1.

Page 10: untuk memenuhi sebagian persyaratan mencapai derajat

vii

h. Ibu dan Ayah tercinta yang senantiasa mendo’akan dan memberikan semangat

dalam perjalanan studi Strata 1 maupun dalam kehidupan penulis.

Akhir kata, penulis mohon maaf atas kekeliruan dan kesalahan yang

terdapat dalam Skripsi ini dan berharap semoga Skripsi ini dapat memberikan

manfaat bagi khasanah pengetahuan Teknologi Informasi di lingkungan STT

Pelita Bangsa khususnya dan Indonesia pada umumnya.

Bekasi, September 2018

Penulis

Page 11: untuk memenuhi sebagian persyaratan mencapai derajat

viii

Daftar Tabel

Halaman

Tabel 2.1 : Jenis-Jenis Penyakit Gigi .................................................... 18

Tabel 2.2 : Hasil Perhitungan ................................................................ 21

Tabel 2.3 : Use Case Diagram ............................................................... 23

Tabel 2.4 : Activity Diagram ................................................................. 24

Tabel 2.5 : Sequence Diagram .............................................................. 25

Tabel 2.6 : Class Diagram ..................................................................... 26

Tabel 2.7 : Perbandingan Studi Literature ............................................. 34

Tabel 3.1 : Use Case Sistem Berjalan ................................................... 39

Tabel 3.2 : Kode Penyakit Gigi .............................................................. 46

Tabel 3.3 : Kode Gejala Penyakit Gigi .................................................. 46

Tabel 3.4 : Gejala Penyakit Gigi ............................................................ 47

Tabel 3.5 : Contoh Tabel Perhitungan Gejala Penyakit Gigi ................ 47

Tabel 3.6 : Tabel tbl_diagnosa ............................................................... 57

Tabel 3.7 : Tabel tbl_gejala .................................................................... 57

Tabel 3.8 : Tabel tbl_penyebab penyakit ............................................... 57

Tabel 3.9 : Tabel tbl_admin ................................................................... 58

Tabel 3.10 : Tabel Rencana Pengujian ..................................................... 58

Tabel 3.11 : Tabel Hasil Pengujian ........................................................... 59

Tabel 4.1 : Use Case Sistem Pakar Gigi ................................................. 62

Tabel 4.2 : Sequence konsultasi .............................................................. 63

Tabel 4.3 : Sequence Basis Aturan ........................................................ 64

Tabel 4.4 : Sequence Daftar Gejala......................................................... 65

Tabel 4.5 : Sequence Buku Tamu ........................................................... 66

Tabel 4.6 : Sequence Laporan ................................................................. 67

Tabel 4.7 : Sequence Pengaturan ............................................................ 68

Tabel 4.8 : Sequence Keluar ................................................................... 69

Tabel 4.9 : Diagram Activity Diagnosa .................................................. 70

Tabel 4.10 : Diagram Activity Basis Aturan ............................................. 71

Page 12: untuk memenuhi sebagian persyaratan mencapai derajat

ix

Tabel 4.11: Diagram Activity Daftar Penyakit ......................................... 72

Tabel 4.12: Diagram Activity Gejala ........................................................ 73

Tabel 4.13 : Diagram Activity Buku Tamu .............................................. 74

Tabel 4.14 : Diagram Activity Hasil Diagnosa ......................................... 75

Tabel 4.15 : Diagram Activity Keluar....................................................... 76

Tabel 4.16 : Pengujian Menu Konsultasi .................................................. 94

Tabel 4.17 : Pengujian Menu Daftar Penyakit ........................................ 95

Tabel 4.18 : Pengujian Menu Buku Tamu ............................................... 95

Tabel 4.19 : Pengujian Menu Mulai Diagnosa ........................................ 95

Tabel 4.20 : Pengujian Menu Gejala ....................................................... 96

Tabel 4.21 : Pengujian Menu Keluar ....................................................... 96

Page 13: untuk memenuhi sebagian persyaratan mencapai derajat

x

Daftar Gambar

Halaman

Gambar 2.1 : Struktur Dan Arsitektur Sistem Pakar ............................... 11

Gambar 2.2 : Bagian-Bagian Gigi .......................................................... 17

Gambar 3.1 : Struktur Organisasi Praktek Drg. Priska .......................... 38

Gambar 3.2 : Use Case Praktek Drg. Priska .......................................... 35

Gambar 3.3 : Desaign Penelitian ............................................................ 40

Gambar 3.4 : Model Waterfall .............................................................. 43

Gambar 3.5 : ERD Implementasi Sistem Pakar Gigi ............................. 49

Gambar 3.6 : Diagram Konteks Implementasi Sistem Pakar Gigi.......... 50

Gambar 3.7 : DFD Level 1 Implementasi Sistem Pakar Gigi ................. 51

Gambar 3.8 : DFD Level 1 Proses 3 Pengelolahan Data ........................ 52

Gambar 3.9 : DFD Level 1 Proses 5 Konsultasi ..................................... 53

Gambar 3.10 : DFD Level 1 Proses 3.1 (Pengelolahan Data Penyebab) .. 53

Gambar 3.11 : DFD Level 1 Proses 3.2 (Pengelolahan Data Gejala) ....... 54

Gambar 3.12 : DFD Level 1 Proses 3.3 (Data Gejala Penyebab) ............. 54

Gambar 3.13 : DFD Level 1 Proses 5.1 (Konsultasi) ............................... 53

Gambar 3.14 : Diagram Relasi Implementasi Sistem Pakar Gigi ............. 56

Gambar 4.1 : Use Case Sistem Pakar Penyakit Gigi .............................. 59

Gambar 4.2 : Diagram Sequence Mulai Diagnosa .................................. 60

Gambar 4.3 : Diagram Sequence Basis Aturan ....................................... 61

Gambar 4.4 : Diagram Sequence Daftar Gejala ...................................... 62

Gambar 4.5 : Diagram Sequence Buku Tamu ....................................... 63

Gambar 4.6 : Diagram Sequence Laporan ............................................. 64

Gambar 4.7 : Diagram Sequence Profile Pengaturan ............................. 65

Gambar 4.8 : Diagram Sequence Keluar ................................................ 66

Gambar 4.9 : Diagram Activity Mulai Diagnosa .................................... 67

Gambar 4.10 : Diagram Activity Basis Aturan ........................................ 68

Gambar 4.11 : Diagram Activity Daftar Penyakit ................................... 69

Gambar 4.12 : Diagram Activity Gejala ................................................. 70

Page 14: untuk memenuhi sebagian persyaratan mencapai derajat

xi

Gambar 4.13: Diagram Activity Buku Tamu ........................................... 71

Gambar 4.14: Diagram Activity Hasil Diagnosa ..................................... 72

Gambar 4.15: Diagram Activity Keluar ................................................... 73

Gambar 4.16: Class Diagram Sistem Pakar Gigi ..................................... 74

Gambar 4.17: Rancangan Tampilan Login .............................................. 75

Gambar 4.18: Rancangan Tampilan Menu Utama ................................... 75

Gambar 4.19: Rancangan Tampilan Menu Mulai Diagnosa .................... 76

Gambar 4.20: Rancangan Tampilan Hasil Diagnosa ............................... 76

Gambar 4.21: Rancangan Tampilan Basis Aturan ................................... 77

Gambar 4.22: Rancangan Tampilan Daftar Gejala .................................. 77

Gambar 4.23: Rancangan Tampilan Buku Tamu ..................................... 78

Gambar 4.24: Rancangan Tampilan Penyakit ........................................... 78

Gambar 4.25: Rancangan Tampilan Hasil Diagnosa ............................... 79

Gambar 4.26: Rancangan Tampilan Keluar ............................................. 80

Gambar 4.27: Tampilan Login ................................................................. 81

Gambar 4.28: Tampilan Menu Utama ..................................................... 81

Gambar 4.29: Tampilan Menu Penyakit .................................................. 82

Gambar 4.30: Tampilan Menu Gejala ....................................................... 82

Gambar 4.31: Tampilan Menu Basis Aturan ........................................... 83

Gambar 4.32: Tampilan Menu Hasil Diagnosa......................................... 83

Gambar 4.33: Tampilan Menu Laporan ................................................... 84

Gambar 4.34: Contoh Tampilan Menu Hasil Laporan ............................. 84

Gambar 4.35: Tampilan Menu Buku Tamu ............................................. 85

Gambar 4.36: Tampilan Menu Pengaturan Admin .................................. 85

Gambar 4.37: Tampilan Menu Logout ..................................................... 86

Gambar 4.38: Tampilan Menu Utama ..................................................... 86

Gambar 4.39: Tampilan Menu Diagnosa ................................................. 87

Gambar 4.40: Tampilan Tampilan Hasil Dignosa ................................... 88

Gambar 4.41: Tampilan Basis Aturan ....................................................... 88

Gambar 4.42: Tampilan Daftar Gejala ...................................................... 89

Gambar 4.43: Tampilan Buku Tamu ........................................................ 89

Page 15: untuk memenuhi sebagian persyaratan mencapai derajat

xii

DAFTAR ISI

Halaman

Lembar Persetujuan .................................................................................. i

Lembar Pengesahan ................................................................................. ii

Abstraksi ( Bahasa Indonesia ) ................................................................. iii

Abstraksi ( Bahasa English ) .................................................................... iv

Surat Pernyataan Keaslian Penelitian........................................................ v

Kata Pengantar .......................................................................................... vi

Daftar Tabel ............................................................................................. viii

Daftar Gambar .......................................................................................... x

Daftar Isi ................................................................................................... xii

BAB I: Pendahuluan ................................................................................ 1

1.1 Latar Belakang ....................................................................... 1

1.2 Identifikasi Masalah ............................................................... 4

1.3 Rumusan Masalah .................................................................. 5

1.4 Batasan Masalah ..................................................................... 5

1.5 Tujuan dan Manfaat Penelitian .............................................. 6

1.5.1 Tujuan Penelitian .......................................................... 6

1.5.2 Manfaat Penelitian ........................................................ 6

1.6 Teknik Pengumpulan Data ..................................................... 6

1.7 Sistematik Penulisan .............................................................. 7

BAB II : Tinjauan Pustaka ....................................................................... 9

2.1 Kecerdasan Buatan ................................................................. 9

2.2 Sistem Pakar ............................................................................ 9

2.2.1 Pengertian Sistem Pakar ................................................ 9

2.2.2 Ciri-Ciri Sistem Pakar .................................................. 10

2.2.3 Struktur Sistem Pakar ................................................... 10

2.2.4 Manfaat Sistem Pakar ................................................... 12

Page 16: untuk memenuhi sebagian persyaratan mencapai derajat

xiii

2.2.5 Konsep Dasar Sistem Pakar .......................................... 13

2.2.5.1 Kepakaran ........................................................ 13

2.2.5.2 Pakar ................................................................ 13

2.2.5.3 Pemindahan Kepakaran ................................... 13

2.2.5.4 Inferensi ............................................................ 14

2.2.5.5 Aturan .............................................................. 14

2.2.5.6 Kemampuan Menjelaskan ................................ 14

2.2.6 Bentuk Sistem Pakar .................................................... 14

2.2.7 Klasifikasi Sistem Pakar .............................................. 15

2.2.8 Kelebihan Sistem Pakar ................................................ 16

2.2.9 Kelebihan Sistem Pakar ................................................ 16

2.3 Gigi ........................................................................................ 17

2.4 Jenis-Jenis Penyakit Gigi ...................................................... 18

2.5 Metode Dempster Shafer ....................................................... 19

2.5.1 Belief.............................................................................. 19

2.5.2 Mass Funcition .............................................................. 20

2.6 UML (Unified Modeling Language) ..................................... 22

2.7 Hypertext Prepocessor (PHP) ............................................... 26

2.8 Hyper Text Markup Language (HTML) ............................... 27

2.9 Diagnosa ................................................................................. 28

2.10 Penyakit ................................................................................ 28

2.11 Database dan MySQL .......................................................... 28

2.12 PHPMyAdmin ...................................................................... 30

2.13 Localhost .............................................................................. 31

2.14 Pengujian Perangkat Lunak .................................................. 31

2.15 Black Box Testing ................................................................ 32

2.16 Tinjauan Objek Penelitian .................................................... 33

BAB III : Analisa Masalah ....................................................................... 36

3.1 Analisa Objek Penelitian ........................................................ 36

3.1.1 Sejarah Praktek Drg. Priska .......................................... 36

3.1.2 Visi dan Misi ................................................................. 36

3.1.3 Struktur Organisasi ....................................................... 37

Page 17: untuk memenuhi sebagian persyaratan mencapai derajat

xiv

3.2 Analisa Sistem Berjalan ......................................................... 38

3.3 Desain Penelitian .................................................................... 39

3.4 Metode Penelitian ................................................................... 43

3.4.1 Metode Pengumpulan Data .......................................... 43

3.4.2 Metode Pengembangan Perangkat Lunak ..................... 43

3.5 Analisis Sistem ....................................................................... 44

3.5.1 Sumber Infomasi .......................................................... 45

3.5.2 Identifikasi Masalah ..................................................... 45

3.5.3 Analisis data Penyebab Penyakit Gigi ......................... 45

3.5.4 Indentifikasi Input ........................................................ 48

3.5.5 Indentifikasi Output....................................................... 48

3.5.6 Analisis Kebutuhan Non Fungsional ............................ 48

3.5.6.1 Analisis Pengguna............................................. 48

3.5.6.2 Analisis Perangkat Keras .................................. 48

3.5.6.3 Analisis Perangkat Lunak ................................. 49

3.5.6.4 Analisis Basis Data ........................................... 49

3.5.6.5 Analisis Kebutuhan Fungsional ........................ 50

3.5.6.5.1 Diagram Konteks ............................... 50

3.5.6.5.2 Data Flow Diagram (DFD) ................ 50

3.6 Pengujian Perangkat Lunak .................................................... 55

3.6.1 Rencana Pengujian ........................................................ 55

3.6.2 Hasil Pengujian ............................................................. 56

3.6.3 Metode Pengembangan Perangkat Lunak ..................... 58

BAB IV : Perancangan dan Implementasi Sistem ................................... 59

4.1 Perancangan Sistem ................................................................ 59

4.2 Design Sistem ......................................................................... 74

4.2.1 Rancangan Tampilan Login ......................................... 74

4.2.2 Rancangan Menu Utama .............................................. 75

4.2.3 Rancangan Menu Mulai Diagnosa ................................ 75

4.2.4 Rancangan Menu Basis Aturan .................................... 77

4.2.5 Rancangan Menu Daftar Gejala ................................... 77

4.2.6 Rancangan Menu Buku Tamu ....................................... 78

Page 18: untuk memenuhi sebagian persyaratan mencapai derajat

xv

4.2.7 Rancangan Menu Penyakit ........................................... 78

4.2.8 Rancangan Menu Hasil Diagnosa ................................. 79

4.2.9 Rancangan Menu Keluar ............................................... 80

4.3 Implementasi Sistem .............................................................. 80

4.3.1 Tampilan Pada Administrator ...................................... 80

4.3.1.1 Tampilan Login Pada Administrator ............... 81

4.3.1.2 Tampilan Menu Utama Pada Administrator ..... 81

4.3.1.3 Tampilan Daftar Penyakit ................................ 82

4.3.1.4 Tampilan Menu Gejala .................................... 82

4.3.1.5 Tampilan Menu Basis Aturan ........................... 83

4.3.1.6 Tampilan Menu Hasil Diagnosa ...................... 83

4.3.1.7 Tampilan Menu Laporan ................................. 84

4.3.1.8 Tampilan Menu Buku Tamu ............................ 85

4.3.1.9 Tampilan Menu Pengaturan ............................. 85

4.2.1.10 Tampilan Menu Logout ................................. 86

4.3.2 Tampilan Pada User ...................................................... 86

4.3.2.1 Tampilan Menu Utama Pada User ................... 86

4.3.2.2 Tampilan Menu Mulai Diagnosa ...................... 87

4.3.2.3 Tampilan Basis Aturan .................................... 88

4.3.2.4 Tampilan Daftar Gejala ................................... 89

4.3.2.5 Tampilan Buku Tamu ....................................... 89

4.4 Pengujian Sistem .................................................................... 90

4.4.1 Spesifikasi Hardware dan Software ............................. 90

4.4.2 Pengujian Pada Menu Konsultasi ................................. 91

4.4.3 Pengujian Pada Menu Daftar Penyakit ......................... 91

4.4.4 Pengujian Pada Menu Buku Tamu ................................ 92

4.4.5 Pengujian Pada Menu Mulai Diagnosa ......................... 92

4.4.6 Pengujian Pada Menu Pada Gejala ............................... 93

4.4.7 Pengujian Pada Menu Keluar ....................................... 93

BAB V : Penutup ..................................................................................... 94

5.1 Kesimpulan ............................................................................. 97

5.2 Saran ....................................................................................... 98

Page 19: untuk memenuhi sebagian persyaratan mencapai derajat

xvi

Daftar Pustaka .......................................................................................... 99

Lampiran 1 ........................................................................................... 101

Page 20: untuk memenuhi sebagian persyaratan mencapai derajat

1

BAB I

PENDAHULUAN

1.1 Latar Belakang

Gigi merupakan salah satu organ terpenting yang ada di dalam tubuh

manusia. Sebagai satu satunya organ yang tidak bisa menyembuhkan dirinya

sendiri, gigi menjadi organ tubuh yang sangat dijaga dan dirawat kondisinya

selama kehidupan seseorang berlangsung. Gigi juga termasuk organ yang sangat

penting dalam proses pengolahan makanan. Seseorang dapat dipastikan akan sulit

mengunyah makanan tanpa adanya gigi. Kesehatan gigi dan mulut penting untuk

diperhatikan dan merupakan bagian integral dari kesehatan secara keseluruhan

yang memerlukan penanganan segera sebelum terlambat dan dapat mempengaruhi

kondisi kesehatan seseorang. Setiap orang perlu mengetahui cara menjaga

kesehatan gigi dan mulut mereka. Pengetahuan tentang kesehatan gigi merupakan

salah satu usaha untuk mencegah dan menanggulangi masalah kesehatan gigi

melalui pendekatan pendidikan kesehatan gigi (Azhary, 2016). Kondisi gigi yang

tidak terjaga dengan baik dapat menyebabkan masalah yang lain di sekitar mulut,

diantaranya timbul gigi yang berlubang, sakit gigi, karang gigi, plak gigi,

peradangan pada gusi, sariawan, dan kelainan-kelainan yang lain disekitar gigi

(Setyaningsih, 2007).

Berdasarkan data yang diperoleh dari analisis lanjut Riskesdas tahun

2007, karakreristik seseorang (umur, pendidikan, tempat tinggal, serta sosial

ekonomi) responden memengaruhi terjadinya penyakit gigi. Semakin tinggi

pendidikan dan semakin tinggi tingkat sosial ekonomi responden semakin kecil

risiko terjadinya penyakit gigi, responden yang tinggal di kota beresiko untuk

terjadinya karies lebih besar dibandingkan responden yang tinggal di desa

(Oktarina, 2010).

Data informasi kesehatan gigi di Indonesia yang diperoleh dari Pusat Data

dan Informasi (Pusdatin) Kementerian Kesehatan RI tahun 2014 mengungkapkan

bahwa presentase penduduk Indonesia yang memiliki masalah kesehatan gigi

Page 21: untuk memenuhi sebagian persyaratan mencapai derajat

2

tahun 2015 dan 2018 meningkat dari 23,2% menjadi 25,9%. Penduduk yang

menerima perawatan medis gigi meningkat dari 29,7% tahun2007 menjadi 31,1%

pada tahun 2018 (Kemenkes RI, 2014).

Pusdatin dan Badan PPSDM (Pengembangan dan Pemberdayaan Sumber

Daya Manusia) melakukan analisis sederhana untuk melihat persebaran tenaga

kesehatan dokter gigi di puskesmas berdasarkan data olahan yang diperoleh pada

tahun 2017. Hasil dari analisis Pusdatin dan PPSDM menunjukkan bahwa

sebagian besar puskesmas di 33 Provinsi masih ada yang “kurang” tenaga dokter

gigi sedangkan provinsi lain memiliki tenaga kesehatan gigi (dokter gigi/ perawat

gigi) berlebih (Kemenkes RI, 2014).

Hasil prevalensi yang telah dilakukan oleh Kemenkes dan PPSDM

menunjukkan bahwa Indonesia memiliki peningkatan pada masalah kesehatan

gigi serta penyebaran tenaga kerja dokter gigi yang ternyata kurang seimbang di

setiap provinsi. Hal ini bisa berdampak pada sulitnya jangkauan dokter gigi pada 3

sebagian daerah pedesaan yang sebetulnya memiliki tingkat kesehatan gigi yang

lebih buruk dibanding di kota.

Idealnya masyarakat seperti ini membutuhkan langkah cepat dalam

memeriksakan gigi mereka sebelum pergi ke dokter gigi yang lokasinya dapat

dibilang jauh dari jangkauan. Hal ini diperuntukan dalam penanggulangan awal

dalam mengatasi penyakit gigi yang mungkin diderita. Oleh karena itu dibutuhkan

cara cepat dalam mendiagnosa penyakit gigi yang dapat dilakukan oleh setiap

individu.

Teknologi sudah semakin berkembang pada era sekarang. Sebagian besar

pekerjaan telah melibatkan teknologi. Sistem pakar menjadi salah satu bagian dari

ilmu kecerdasan buatan yang berkembang pesat dalam dunia teknologi. Dengan

sistem pakar, seseorang dapat terbantu sesuai dengan kebutuhan disaat sulit untuk

menemui para pakar secara langsung. Sistem pakar dapat membantu dalam

menyelesaikan masalah dan juga sebagai perwakilan dari para pakar. Dengan

adanya teknologi kecerdasan semacam ini seseorang dapat menghemat waktu

serta biaya. Sistem pakar menyediakan solusi yang disederhanakan dalam kasus

Page 22: untuk memenuhi sebagian persyaratan mencapai derajat

3

rumit yang berulang – ulang. Implementasinya dapat dibangun dalam bentuk web

based ataupun mobile.

Silvia dkk (2015) telah melakukan penelitian untuk mendiagnosa karies

sesorang melalui aplikasi berbasis web yang ditulis dalam sebuah jurnal yang

berjudul “Aplikasi Diagnosis Karies pada Gigi Manusia Berbasis Web”.

Pengguna diminta untuk menjawab pertanyaan dan jawaban yang diperoleh akan

disesuaikan dengan rules dalam sistem untuk memberikan kesimpulan.

Penelitian sistem pakar juga dibuat oleh (Masykur, 2012) menggunaka

metode lain dengan judul ”Implementasi Sistem Pakar Diagnosis Penyakit

Diabetes Mellitus Menggunakan Metode Fuzzy Logic Berbasis Web”. Sistem

pakar fuzzy logic dapat diterapkan menggunakan aplikasi web karena dengan

aplikasi web bisa mudah digunakan oleh semua pihak tanpa batasan waktu.

Dengan digunakan aplikasi web, pengguna dapat dengan mudah dan cepat

mengakses sistem.

Penelitian sistem pakar juga dibuat oleh (Masykur, 2012) menggunakan

metode lain dengan judul ”Implementasi Sistem Pakar Diagnosis Penyakit

Diabetes Mellitus Menggunakan Metode Fuzzy Logic Berbasis Web”. Sistem

pakar fuzzy logic dapat diterapkan menggunakan aplikasi web karena dengan

aplikasi web bisa mudah digunakan oleh semua pihak tanpa batasan waktu.

Dengan digunakan aplikasi web, pengguna dapat dengan mudah dan cepat

mengakses sistem.

Maka didasarkan oleh fakta – fakta yang ada serta penelitian-penelitian

sebelumnya yang berkaitan, penulis berinisiatif untuk membuat suatu sistem pakar

diagnosa penyakit gigi berbasis web menggunakan metode Dempster Shafer

yang berguna bagi penderita penyakit gigi dalam mendiagnosa penyakit giginya

sendiri. Data mengenai nama penyakit, gejala, serta penanganannya didapatkan

langsung dari pakar yang memahami ilmu penyakit gigi. Diharapkan dengan

adanya sistem ini masyarakat bisa memperoleh gambaran akan penyakit gigi

yang sedang dialami dan dengan mudah dapat mengonsultasikan kepada dokter

gigi setelahnya.

Page 23: untuk memenuhi sebagian persyaratan mencapai derajat

4

Dengan adanya masalah tersebut maka perlu adanya solusi yang tepat dan

mudah bagi masyarakat dalam membatu menangani masalah penyakit gigi.

Masyarakat memerlukan sebuah sistem pendeteksi penyakit gigi berbasis Website

untuk mengetahui gejala serta cara penanganan yang tepat yang dapat membantu

memberikan informasi tentang penyakit gigi tersebut. Sistem pakar pendeteksi

penyakit gigi ini menggunakan metode Dempster Shafer, suatu teori matematika

untuk pembuktian berdasarkan belief function and plausible reasoning (fungsi

kepercayaan dan pemikiran yang masuk akal), yang digunakan untuk menyatukan

potongan informasi yang terpisah (bukti) untuk menghitung kemungkinan dari

suatu peristiwa. Teori ini dikembangkan oleh Arthur P.Dempster dan glenn

Shafer. Berdasarkan latar belakang di atas, timbul pemikiran penulis untuk

membuat suatu sistem kepakaran untuk mendeteksi penyakit gigi serta cara

penanganan yang tepat, tujuan dari penelitian ini adalah membangun suatu sistem

berbasis pengetahuan kedokteran dalam mendiagnosa penyakit gigi yang

ditampilkan dalam website menggunakan pemograman PHP dengan database

MySQL dan menjadikannya materi skripsi dengan judul “IMPLEMENTASI

SISTEM PAKAR MENGGUNAKAN METODE DEMPSTER SHAFER

UNTUK MENDETEKSI PENYAKIT GIGI”. Dengan sistem ini diharapkan dapat

membantu manusia dalam menangani masalah penyakit gigi secara akurat,

sebagai mana telah diterapkan sistem kepakaran dibidang - bidang lainnya.

1.2. Identifikasi Masalah

Dari hasil pemaparan latar belakang maka dapat identifikasikan

permasalahan sebagai berikut :

(1) Rendahnya kesadaran masyarakat serta informasi yang kurang akan

kesehatan gigi.

(2) Mahalnya biaya untuk memeriksakan kesehatan gigi ke ke dokter, sehingga

masyarakat cenderung mengobati sendiri dengan cara yang belum tentu

benar.

Page 24: untuk memenuhi sebagian persyaratan mencapai derajat

5

(3) Perlu adanya sistem kepakaran gigi yang mudah diakses, untuk mendiagnosa

penyakit gigi guna menjaga kesehatan gigi bagi masyarakat.

1.3. Rumusan Masalah

Berdasarkan latar belakang masalah yang diuraikan di atas, maka penulis

selanjutnya menyimpulkan masalah - masalah yang terjadi sebagai berikut :

(1) Bagaimana menerapkan suatu sistem pakar yang mudah diakses oleh

masyarakat ?

(2) Bagaimana mengimplementasikan sebuah sistem ke perangkat komputer

dengan metode Dempster Shafer ?

(3) Bagaimana membuat sistem pakar untuk mendiagnosa penyakit gigi dengan

akurasi tinggi ?

(4) Bagaimana membuat sistem pakar yang dapat mengetahui jenis penyakit gigi

serta penanganan yang tepat ?

1.4. Batasan Masalah

Untuk memfokuskan penelitian ini maka penulis membatasi masalah -

masalah yang timbul, adapun batasan masalah dari pembuatan sistem ini sebagai

berikut:

(1) Aplikasi hanya menganalisa jenis penyakit gigi yang umum pada manusia.

Sistem kepakaran ini dapat dijalankan dengan baik melalui aplikasi browser

seperti Internet Explorer, Mozila Firefox, Opera, Google Chrome, Netscape

Navigator, Mozaic, Avant Browser dan lain-lain.

(2) Hasil dari sistem ini berupa jenis penyakit, visualisasi penyakit serta cara

penanggulanganya.

(3) Aplikasi program berbasis Website dengan menggunakan PHP dan database

MySQL.

Page 25: untuk memenuhi sebagian persyaratan mencapai derajat

6

1.5. Tujuan dan Manfaat Penelitian

1.5.1. Tujuan Penelitian

Berdasarkan latar belakang dan penjelasan yang menjadi dasar

pengembangan sistem pakar ini, tentunya ada tujuan yang ingin dicapai penulis

dalam pengembangan sistem pakar untuk mendiagnosa penyakit gigi, adapun

target atau hasil yang ingin dicapai bertujuan untuk :

(1) Membangun sistem pakar untuk menganalisa penyakit gigi yang dapat

membantu masyarakat dalam mengetahui jenis penyakit gigi yang

dideritanya.

(2) Dapat memberikan peran untuk meningkatkan kesehatan masyarakat

Indonesia terutama dalam penyakit gigi.

(3) Untuk membantu agar penderita penyakit gigi dapat mengambil tindakan

dengan cepat, sehingga penyakitnya dapat segera diatasi.

1.5.2. Manfaat Penelitian

(1) Hasil penelitian ini diharapkan menjadi bahan masukan, sehingga sistem ini

menjadi acuan untuk para peneliti lainnya yang ingin mengembangkan sistem

yang sejenis.

(2) Penelitian ini diharapkan bisa menghasilkan sistem yang benar - benar dapat

memberikan solusi bagi masyarakat khususnya dalam mengurangi tingginya

angka penderita penyakit gigi.

1.6 Teknik Pengumpulan Data

Teknik pengumpulan data yang dilakukan penulis adalah metode

deskriptif yaitu metode penelitian yang dilakukan untuk menggambarkan proses

peristiwa yang sedang terjadi pada saat dilakukan penelitian.

Untuk mendapatkan informasi–informasi dan mengumpulkan data yang

diperlukan guna menyelesaikan skripsi ini, maka penulis melakukan teknik

pengumpulan data seperti berikut :

Page 26: untuk memenuhi sebagian persyaratan mencapai derajat

7

1. Wawancara (Interview)

Untuk memperolah kelengkapan data yang lebih rinci lagi, penulis bertanya

langsung pada pihak-pihak yang terkait untuk memperoleh data yang lebih

akurat.

2. Pengamatan (Observation)

Metode observation yaitu salah satu tehnik pengumpulan data yang efektif

dalam mempelajari sistem, dengan cara mengamati langsung kegiatan.

3. Studi Kepustakaan (Library Research)

Untuk melengkapi data yang didapatkan dalam penulisan skripsi ini, penulis

juga menggunakan metode kepustakaan yaitu mengumpulkan data yang

diperlukan melalui buku–buku diktat, serta sumber lain yang menunjang dan

berhubungan dalam penulisan skripsi.

1.7 Sistematika Penulisan

Dalam penyusunan laporan skripsi ini akan diuraikan dalam bentuk bab, dan

masing - masing bab akan dipaparkan dalam beberapa sub bab, diantaranya :

BAB I

PENDAHULUAN

Bab ini berisikan paparan mengenai latar belakang masalah, identifikasi

masalah, rumusan masalah, batasan masalah, tujuan dan manfaat penelitian, tata

urut penulisan.

BAB II

TINJAUAN PUSTAKA

Dalam bab ini akan membahas referensi terkait dengan topik sistem pakar

untuk mendiagnosa penyakit gigi, dan juga referensi dari sistem yang telah dibuat

sebelumnya dengan algoritma yang berbeda.

Page 27: untuk memenuhi sebagian persyaratan mencapai derajat

8

BAB III

ANALISA MASALAH

Bab ini terdiri dari analisa sistem dan perancangan dari sistem yang sedang

berjalan. Serta memaparkan sistem yang diusulkan untuk menangani masalah

yang ada. Pada bagian perancangan sistem, membahas tentang perancangan

variabel indikator penentu penyakit gigi ke dalam himpunan dempster shafer dan

perancangan yang akan diimplementasikan pada sistem.

BAB IV

IMPLEMENTASI DAN PENGUJIAN SISTEM

Menjelaskan tentang perancangan, implementasi sistem, pengujian sistem

serta analisa terhadap permasalahan yang dibahas dalam penelitian, interpretasi

masalah penelitian serta implikasi dari penelitian.

BAB V

PENUTUP

Bab ini merupakan penutup yang memuat kesimpulan dari keseluruhan

uraian bab - bab sebelumnya.

Page 28: untuk memenuhi sebagian persyaratan mencapai derajat

9

BAB II

TINJAUAN PUSTAKA

2.1 Kecerdasan Buatan

Kecerdasan buatan berasal dari bahasa Inggris “Artificial Intelligence” atau

singkatan AI, yaitu intelligence adalah kata sifat yang berarti cerdas, sedangkan

artificial artinya buatan. Kecerdasan buatan yang dimaksud di sini merujuk pada

mesin yang mampu berpikir, menimbang tindakan yang akan diambil dan mampu

mengambil keputusan seperti yang dilakukan oleh manusia (Sutojo dkk, 2011).

Menurut Handojo dan Irawan (2009), kecerdasan buatan adalah cabang ilmu

komputer yang bertujuan untuk membuat sebuah komputer dapat berpikir dan

bernalar seperti manusia. Kecerdasan buatan dapat membantu manusia dalam

membuat keputusan, mencari informasi secara lebih akurat, atau membuat

komputer lebih mudah digunakan dengan tampilan yang menggunakan bahasa

natural sehingga mudah dipahami. Salah satu bagian dari sistem kecerdasan

buatan adalah sistem pakar dimana sistem pakar adalah bagian dari ilmu

kecerdasan buatan yang secara spesifik berusaha mengadopsi kepakaran

seseorang di bidang tertentu ke dalam suatu sistem atau program komputer.

2.2 Sistem Pakar

2.2.1. Pengertian Sistem Pakar

Sistem pakar merupakan sebuah program yang berfungsi untuk menirukan

seorang pakar atau ahli sehingga program tersebut dapat melakukan apa yang

dikerjakan oleh seorang pakar. Pembentukan sistem pakar didasarkan pada suatu

ide dengan mentransfer pengetahuan seorang pakar ke dalam komputer.

Pengetahuan yang tersimpan itu digunakan untuk menyelesaikan masalah yang

sesuai dengan pengetahuan yang telah diperoleh. Dengan adanya sistem pakar,

maka keluaran yang akan dihasilkan lebih efektif, terorganisir, dan

Page 29: untuk memenuhi sebagian persyaratan mencapai derajat

10

tepatdibandingkan dengan keluaran yang dihasilkan oleh manusia (Hartati dkk,

2008).

Sistem pakar merupakan cabang dari Artificial Intelligence (AI) yang

dikembangkan pada pertengahan 1960. Sistem pakar berasal dari istilah

knowledge-based expert system, yaitu sebuah sistem yang menggunakan

pengetahuan manusia dimana pengetahuan tersebut dimasukkan kedalam

komputer dan kemudian digunakan unruk menyelesaikan masalah-masalah yang

biasanya membutuhkan kepakaran atau keahlian manusia (Sutojo dkk, 2011).

2.2.2 Ciri-Ciri Sistem Pakar

Menurut Sutojo dkk (2011), ciri-ciri sistem pakar adalah :

1. Terbatas pada domain keahlian tertentu,

2. Dapat memberikan penalaran-penalaran untuk data-data yang tidak lengkap

atau tidak pasti,

3. Dapat mengemukakan rangkaian alasan-alasan yang diberikannya dengan cara

yang dapat dipahami,

4. Berdasarkan pada kaidah/ketentuan/rule tertentu,

5. Dirancang untuk dapat dikembangkan secara bertahap,

6. Pengetahuan dan mekanisme penalaran (inference) jelas terpisah,

7. Keluarannya bersifat anjuran,

8. Sistem dapat mengaktifkan kaidah secara searah yang sesuai dituntun oleh

dialog dengan user.

2.2.3 Struktur Sistem Pakar

Menurut Sutojo dkk. (2011) dan Siswanto (2010), sistem pakar disusun

oleh dua bagian utama, yaitu bagian lingkungan pengembangan (development

environment) dan lingkungan konsultasi (consulation environment). Lingkungan

pengembang digunakan oleh pembuat sistem pakar untuk membangun komponen

komponennya dan memperkenalkan pengetahuan ke dalam knowledge base (basis

pengetahuan). Sedangkan lingkungan konsultasi digunakan oleh pengguna untuk

Page 30: untuk memenuhi sebagian persyaratan mencapai derajat

11

berkonsultasi sehingga pengguna mendapatkan pengetahuan dan nasihat

darisistem pakar layaknya berkonsultasi dengan seorang pakar.

Gambar 2.1 Struktur dan arsitektur sistem pakar

Sumber : Seminar Nasional Ilmu Komputer UNDIP, Agustus 2010

Pada Gambar 2.1 dapat dijelaskan sebagai berikut :

1. Akuisisi Pengetahuan

Subsistem ini digunakan untuk memasukkan pengetahuan dari seorang pakar

dengan cara merekayasa pengetahuan agar bisa diproses oleh komputer dan

meletakkannya ke dalam basis pengetahuan dengan format tertentu.

2. Basis pengetahuan (knowledge base)

Basis pengetahuan berisi pengetahuan yang diperlukan untuk memahami,

memformulasikan dan menyelesaikan masalah. Basis pengetahuan terdiri dari

dua elemen dasar yaitu fakta dan rule atau aturan.

3. Mesin inferensi (Interference Engine)

Mesin inferensi adalah sebuah program yang berisi metodologi yang digunakan

untuk melakukan penalaran terhadap informasi-informasi dalam basis

pengetahuan untuk memformulasikan konklusi.

4. Daerah kerja (Blackboard)

Daerah kerja yaitu area pada memori yang berfungsi sebagai basis data. Ada

tiga tipe keputusan yang dapat direkam pada blackboard yaitu rencana, agenda

dan solusi.

LINGKUNGAN KONSULTASI LINGKUNGAN PENGEMBANGAN

Fakta tentang

Kejadian tertentu Akuisisi

Pengetahuan

Pemakai

Antar Muka

Aksi Yang

Direkomendasikan

Pasilitas

Penjelasan

Mesin Inferensi

Workspace

Basis pengetahuan fakta

dan aturan

Perbaikan

pengetahuan

Pakar

Knowledge

Engineer

Page 31: untuk memenuhi sebagian persyaratan mencapai derajat

12

5. Antarmuka (User Interface)

Antarmuka digunakan sebagai media komunikasi antara pengguna dan sistem

pakar. Program akan mengajukan pertanyaan-pertanyaan dnan sistem pakar

akan mengambil kesimpulan berdasarkan jawaban dari user.

6. Subsistem penjelasan (Explanation Subsystem)

Subsistem penjelasan berfungsi memberi penjelasan kepada user, bagaimana

suatu kesimpulan dapat diambil.

2.2.4 Manfaat Sistem Pakar

Menurut Sutojo dkk (2011) sistem pakar menjadi populer karena sangat banyak

kemampuan dan manfaat yang diberikannya, di antaranya sebagai berikut.

1. Meningkatkan produktivitas, karena sistem pakar dapat bekerja lebih cepat

daripada manusia.

2. Membuat seorang yang awam bekerja seperti layaknya seorang pakar.

3. Meningkatkan kualitas, dengan memberi nasihat yang konsisten dan

mengurangi kesalahan.

4. Mampu menangkap pengetahuan dan kepakaran seseorang.

5. Dapat beroperasi di lingkungan yang berbahaya.

6. Memudahkan akses pengetahuan seorang pakar.

7. Handal, sistem pakar tidak pernah menjadi bosan dan kelelahan atau sakit.

8. Meningkatkan kapabilitas sistem komputer. Integrasi sistem pakar dengan

sistem komputer lain membuat sistem lebih efektif dan mencakup lebih

banyak aplikasi.

9. Mampu bekerja dengan informasi yang tidak lengkap atau tidak pasti.

10. Bisa digunakan sebagai media pelengkap dalam pelatihan. Pengguna pemula

yang bekerja dengan sistem pakar akan menjadi lebih berpengalaman karena

adanya fasilitas penjelas yang berfungsi sebagai guru.

11. Meningkatkan kemampuan untuk menyelesaikan masalah

Page 32: untuk memenuhi sebagian persyaratan mencapai derajat

13

2.2.5 Konsep Dasar Sistem Pakar

Menurut Sutojo dkk (2011) konsep dasar sistem pakar meliputi enam hal

sebagai berikut.

2.2.5.1 Kepakaran

Kepakaran merupakan suatu pengetahuan yang diperoleh dari pelatihan,

membaca, dan pengalaman. Kepakaran inilah yang memungkinkan para ahli dapat

mengambil keputusan lebih cepat dan lebih baik daripada seseorang yang bukan

pakar. Kepakaran itu sendiri meliputi pengetahuan sebagai berikut.

1. Fakta-fakta pada lingkup permasalahan tertentu.

2. Teori-teori pada lingkup permasalahan tertentu.

3. Prosedur-prosedur dan aturan-aturan berkenaan dengan lingkup permasalahan

1. tertentu.

4. Strategi-strategi global untuk menyelesaikan masalah.

5. Meta-knowledge (pengetahuan tentang pengetahuan).

2.2.5.2 Pakar

Pakar adalah seseorang yang mempunyai pengetahuan, pengalaman, dan

metode khusus serta mampu menerapkannya untuk memecahkan masalah atau

memberi nasihat. Seorang pakar harus mampu menjelaskan dan mempelajari hal-

hal baru yang berkaitan dengan topik permasalahan, jika perlu harus mampu

menyusun kembali pengetahuan-pengetahuan yang didapatkan, dan dapat

memecahkan aturan-aturan serta menentukan relevansi kepakarannya.

2.2.5.3 Pemindahan Kepakaran

Tujuan dari sistem pakar adalah memindahkan kepakaran dari seorang

pakar ke dalam komputer, kemudian ditransfer kepada orang lain yang bukan

pakar. Proses ini melibatkan empat kegiatan, yaitu :

1. Akuisisi pengetahuan (dari pakar atau sumber lain),

2. Representasi pengetahuan (pada komputer),

3. Inferensi pengetahuan,

4. Pemindahan pengetahuan ke pengguna.

Page 33: untuk memenuhi sebagian persyaratan mencapai derajat

14

2.2.5.4 Inferensi

Inferensi adalah sebuah prosedur yang mempunyai kemampuan dalam

melakukan penalaran. Inferensi ditampilkan pada suatu komponen yang disebut

mesin inferensi yang mencakup prosedur-prosedur mengenai pemecahan masalah.

Semua pengetahuan yang dimiliki oleh seorang pakar disimpan pada basis

pengetahuan oleh sistem pakar. Tugas mesin inferensi adalah mengambil

kesimpulan berdasarkan basis pengetahuan yang dimilikinya.

2.2.5.5 Aturan-aturan

Kebanyakan aplikasi sistem pakar komersial adalah sistem yang berbasis

rule (rulebased system), yaitu pengetahuan disimpan terutama dalam bentuk rule,

sebagai prosedur-prosedur pemecahan masalah.

2.2.5.6 Kemampuan Menjelaskan

Fasilitas lain dari sistem pakar adalah kemampuannya untuk menjelaskan

saran atau rekomendasi yang diberikannya. Penjelasan dilakukan dalam subsistem

yang disebut subsistem penjelasan (explanation). Bagian dari sistem ini

memungkinkan sistem untuk memeriksa penalaran yang dibuatnya sendiri dan

menjelaskan operasioperasinya.

2.2.6 Bentuk Sistem Pakar

Sistem pakar dibagi menjadi empat bentuk, yaitu sebagai berikut.

1. Berdiri Sendiri

Sistem pakar jenis ini merupakan perangkat lunak yang berdiri sendiri tidak

bergabung dengan software lainnya.

2. Tergabung

Sistem pakar jenis ini merupakan bagian program yang terkandung di dalam

suatu algoritma (konvensional), atau merupakan program dimana di dalamnya

memanggil algoritma subrutin lain (konvensional).

3. Menghubungkan ke perangkat lunak lain

Bentuk ini biasanya merupakan sistem pakar yang menghubungkan ke suatu

paket program tertentu, misalnya DBMS.

Page 34: untuk memenuhi sebagian persyaratan mencapai derajat

15

4. Sistem Mengabdi

Sistem pakar merupakan bagian dari komputer khusus yang dihubungkan

dengan suatu fungsi tertentu. Misalnya sistem pakar yang digunakan untuk

membantu menganalisis data radar.

2.2.7 Klasifikasi Sistem Pakar

Menurut Siswanto (2005), klasifikasi sistem pakar berdasarkan

kegunaannya adalah sebagai berikut.

1. Diagnosis

Diagnosis digunakan untuk merekomendasikan obat untuk orang sakit,

kerusakan mesin, kerusakan rangkaian elektronik. Bertujuan menemukan

masalah/kerusakan yang terjadi. Biasanya menggunakan pohon keputusan

(decision tree) sebagai representasi pengetahuannya.

2. Pengajaran

Pengajaran digunakan untuk pengajaran, mulai dari SD s/d PT. Membuat

diagnosa apa kekurangan dari siswa, kemudian memberikan solusi atau cara

untuk memperbaikinya.

3. Interpretasi

Untuk menganalisa data yang tidak lengkap, tidak teratur, dan data yang

kontradiktif. Misal : untuk interpretasi citra.

5. Prediksi

Misalnya bagaimana seorang pakar meteorologi memprediksi cuaca besok

berdasarkan data-data sebelumnya. Untuk melakukan peramalan suatu kasus.

5. Perencanaan

Digunakan untuk merencanakan suatu pekerjaan misalnya, perencanaan

mesinmesin dan manajemen bisnis. Untuk menghemat biaya, waktu, &

material, sebab pembuatan model sudah tidak diperlukan. Contoh : sistEM

konfigurasi komputer.

6. Kontrol

Digunakan untuk mengontrol kegiatan yang membutuhkan presisi waktu

tinggi. Misal: pengontrolan pada industri-industri berteknologi tinggi.

Page 35: untuk memenuhi sebagian persyaratan mencapai derajat

16

2.2.8 Kelebihan Sistem Pakar

Menurut Kusumadewi, 2003 dalam bukunya mengatakan sistem pakar

memiliki kemampuan atau kelebihan sebagai berikut :

a. Dapat melakukan proses berulang secara otomatis

b. Mampu meningkatkan output dan suatu produktivitas

c. Dapat menyimpan pengetahuan dan keahlian para pakar

d. Bisa dilakukan oleh orang awam selayaknya mengerjakan pekerjaan para

ahli

e. Meningkatkan kapabilitas dalam menyelesaikan masalah

f. Mampu mengambil dan melestarikan keahlian para pakar

g. Meningkatkan kualitas

h. Mempunyai kemampuan dalam bekerja dengan informasi yang kurang

lengkap dan mengandung ketidakpastian

i. Relatif mempunyai kemampuan dalam mengakses pengetahuan

j. Mampu beroperasi dalam lingkungan yang berbahaya

k. Meningkatkan kapasitas komputer

l. Memiliki reliabilitas

m. Menjadi media pelengkap dalam pelatihan

n. Proses sangat cepat dalam pengambilan keputusan sehingga dapat

menghemat waktu

2.2.9 Kelemahan Sistem Pakar

a. Terkadang sistem tidak dapat membuat keputusan

b. Sulit dikembangkan

c. Sangat sulit dalam pembuatan aplikasi sistem pakar yang berkualitas tinggi

dan membutuhkan biaya yang tinggi dalam pemeliharaan dan

pengembangannya

d. Proses mendapatkan pengetahuan tidak bisa di dapat dengan mudah

e. Sistem pakar tidak 100% benar dalam pengaplikasianya sehingga perlu

selalu diuji ulang secara teliti sebelum digunaka.

Page 36: untuk memenuhi sebagian persyaratan mencapai derajat

17

2.3 Gigi

Gigi adalah jaringan tubuh yang paling keras dibanding yang lainya.

Strukturnya berlapis - lapis mulai dari email yang amat keras, dentin (tulang gigi)

di dalamnya, pulpa yang berisi pembuluh darah, pembuluh saraf, dan bagian lain

yang memperkokoh gigi. Namun demikian, gigi merupakan jaringan tubuh yang

mudah sekali mengalami kerusakan. Ini terjadi ketika gigi tidak memeperoleh

perawatan semestinya (Kusumawardani, 2011).

Gigi merupakan bagian keras yang terdapat didalam mulut yang berfungsi

untuk mengunyah makanan. Gigi terdiri dari beberapa bagian - bagian, berikut ini

gambar dari bagian - bagian gigi :

Gambar 2.2 Bagian - bagian gigi

Sumber : http://id.wikipedia.org/wiki/Gigi

Gigi tersusun atas lapisan-lapisan yang terdiri dari :

(1) Email : merupakan lapisan terluar yang kuat dan keras.

(2) Dentin : Lapisan di bawah email yang lebih lunak dan mudah rusak.

(3) Pulpa : Lapisan yang berisi pembuluh darah dan saraf.

(4) Gusi : Jaringan lunak yang ada dalam mulut.

(5) Cementum : Lapisan luar akar gigi.

(6) Jaringan periodontal : Jaringan yeng memegang gigi sehingga melekat

dalam tulang rahang.

(7) Tulang alveolar : Tulang tempat melekatnya gigi

Page 37: untuk memenuhi sebagian persyaratan mencapai derajat

18

Gigi terbagi atas beberapa jenis yang terdiri dari :

(1) Gigi seri, yaitu jenis gigi yang berbentuk seperti pahat gigi.

(2) Taring, yaitu jenis gigi yang berbentuk runcing.

(1) Geraham, yaitu jenis gigi dengan berbentuk permukaan yang berlekuk –

lekuk (Kusumawardani, 2011) .

2.4 Jenis-jenis Penyakit Gigi

Berdasarkan modul Penyakit Gigi oleh Kristiani dkk (2010) dipaparkan

beberapa jenis penyakit gigi diantaranya adalah sebagai berikut :

Tabel 2.1 Jenis-Jenis Penyakit Gigi

No Penyakit Uraian Contoh Penyakit

1 Caries

Caries adalah kerusakan

yang terbatas apada

jaringan gigi mulai dari

email gigi hingga menjalar

ke dentin (tulang gigi)

2 Abses

periapikal

Abses periapikal adalah

pengumpulan nanah yang

telah menyebar dari

sebuah gigi ke jaringan di

sekitarnya, biasanya

berasal dari suatu infeksi

3 Gigivitis (gusi

bengkak)

Gingivitis adalah

peradangan pada gusi.

Gingivitis terjadidan bisa

timbul kapan saja setelah

tumbuhnya gigi atau

akibat penggosokan dan

cara memebersihkan gigi

yang tidak benar sehingga

plak masih ada di

sepanjang garis gusi.

Page 38: untuk memenuhi sebagian persyaratan mencapai derajat

19

4

Pulpitis

(radang pulpa

gigi)

Pulpitis adalah

peradangan pada pulpa

gigi yang menimbulkan

rasa nyeri. Pulpa adalh

bagian gigi paling dalam,

yang mengandung saraf

dan pembuluh darah

5 Periodontitis

Periodontitis terjadi jika

gingivitis (Gusi bengkak)

meyebar ke seluruh

struktur penyangga gigi

6 Malocclusion

Malocclusion adalah

Kelainan susunan bagian

atas dan bawah rahang

yang mencegah gigi

bertemu dengan

semestinya

2.5 Metode Dempster Shafer

Teori Dempster-Shafer adalah suatu teori matematika untuk pembuktian

berdasarkan belief functions and plausible reasoning (fungsi kepercayaan dan

pemikiran yang masuk akal), yang digunakan untuk mengkombinasikan potongan

informasi yang terpisah (bukti) untuk mengkalkulasi kemungkinan dari suatu

peristiwa. Teori ini dikembangkan oleh Arthur P. Dempster dan Glenn Shafer.

Secara umum Teori Dempster-Shafer ditulis dalam suatu interval:

[Belief, Plausibility]

2.5.1 Belief

Belief Adalah ukuran kekuatan evidence (gejala) dalam mendukung suatu

himpunan bagian. Jika bernilai 0 maka mengindikasikan bahwa tidak ada

evidence, dan jika bernilai 1 menunjukkan adanya kepastian.

Plausibility (Pl) dinotasikan sebagai : Pl(s)= 1 – Bel(¬s)

Plausibility juga bernilai 0 sampai 1. Jika kita yakin akan ¬s, maka dapat

dikatakan bahwa Bel(¬s)=1, dan Pl(¬s)=0. Plausability akan mengurangi tingkat

Page 39: untuk memenuhi sebagian persyaratan mencapai derajat

20

kepercayaan dari evidence. Pada teori Dempster-Shafer kita mengenal adanya

frame of discernment yang dinotasikan dengan θ dan mass function yang

dinotasikan dengan m. Frame ini merupakan semesta pembicaraan dari

sekumpulan hipotesis sehingga disebut dengan environment.

Misalkan: θ = {A, B, C, D, E, F, G, H}

Dengan :

A = Caries/ Gigi berlubang

B = Pulpitis

C = Gingivitis

D = Abses gigi

E = Malocclusion

F = Gigi berjejal

G = Impaksi

H = Malposisi akibat trauma

2.5.2 Mass Function

Sedangkan mass function (m) dalam teori Dempster-Shafer adalah tingkat

kepercayaan dari suatu evidence measure sehingga dinotasikan dengan (m). Untuk

mengatasi sejumlah evidence pada teori Dempster-Shafer menggunakan aturan

yang lebih dikenal dengan Dempster’s Rule of Combination.

Dengan :

m1 (X) adalah mass function dari evidence X

m2 (Y) adalah mass function dari evidence Y

m3 (Z) adalah mass function dari evidence Z

κ adalah jumlah conflict evidence

Contoh Kasus Konsultasi Penyebab Penyakit

Untuk mengetahui hasil konsultasi penyebab penyakit ini, maka dilakukan

pengujian proses konsultasi. Proses pengujian sistem berupa masukkan data gejala

Page 40: untuk memenuhi sebagian persyaratan mencapai derajat

21

yang dialami pada anak yang sering menkonsumsi permen. Pada pegujian pertama

diberikan beberapa gejala yang dialami oleh anak antara lain :

G-1 (Terasa ngilu saat makan dan minum)

G-2 ( Gigi tampak cokelat dan membentuk lubang)

Dari hasil konsultasi, total gejala yang dipilih sebanyak 2 gejala, maka

untuk memperoleh nilai kepercayaan dengan Dempster’s rule of combination dari

gejala yang dipilih, dihitung:

Dimisalkan :

m1(G-1) = 0.15

m1(ѳ) = 1- m1(G-1) = 1- 0.15 = 0.85

m2(G-2) = 0.4

m2(ѳ) = 1- m2 (G-2)= 1- 0.4=0.6

Hasil perhitungan dapat dilihat pada tabel dibawah :

Tabel 2.2 Hasil Perhitungan

Sumber : Jurnal UNIKOM Fitria Nur Ellyani

Langkah pertama hitung nilai dari K-1

K-1

= 1- 0.06 = 0.94

Selanjutnya akan menghitung tingkat kepercayaan (m) combine dengan rumus:

∑ m1(G-1).m2(ѳ)

G-1n ѳ =G-1

m1 ⊕ m2(G-1) = 1 - K

= 0.09/0.94

= 0.0957

kemudian menghitung :

∑ m1(ѳ).m2(G-2)

G-1n ѳ =G-1

Page 41: untuk memenuhi sebagian persyaratan mencapai derajat

22

m1 ⊕ m2(G-2) = 1 - K

= 0.34/0.94

= 0.3617

Jika menggunakan rumus :

bel(X) = ∑ m(Y)

Y⊆X

bel({G-1,G-2}) = bel(G-1) + bel (G-2)

= m1⊕ m2(G-1) + m1⊕ m2(G-2)

= 0.0957 + 0.3617 = 0.4574

= 0.457 * 100 % = 45.7 %

Maka nilai kepastian kombinasi Dempster-Shafer bahwa anak Anda

terkena penyakit yang disebabkan oleh caries/gigi berlubang adalah sebesar

45.7%.

2.6 UML ( Unified Modeling Language )

Unified Modelling Language (UML) adalah sebuah “bahasa” yang telah

menjadi standar dalam industri untuk visualisasi, merancang dan men-

dokumentasikan sistem piranti lunak. UML menawarkan sebuah standar untuk

merancang model sebuah sistem. Dengan menggunakan UML dapat dibuat model

untuk semua jenis aplikasi piranti lunak, dimana aplikasi tersebut dapat berjalan

pada piranti keras, sistem operasi dan jaringan apapun, serta ditulis dalam bahasa

pemrograman apapun (Prastuti, 2009).

UML merupakan sebuah bahasa untuk mensfesifikasikan standar atau

mendokumentasikan standar sebuah sistem.

Ada beberapa jenis diagram yang dapat digunakan sebagai permodelan

sistem, pada sistem ini menggunakan empat jenis diagram yaitu :

(1) Diagram Use-Case bersifat statis. Diagram ini memperlihatkan himpunan

use-case dan aktor - aktor (Prabowo, 2013).

Page 42: untuk memenuhi sebagian persyaratan mencapai derajat

23

(2) Diagram interaksi dan Sequence ( urutan ). Bersifat dinamis. Diagram

urutan adalah diagram interaksi yang menekankan pada pengiriman pesan

dalam suatu waktu tertentu (Prabowo, 2013).

(3) Diagram Aktivitas ( Activity Diagram ). Bersifat dinamis. Diagram

aktivitas adalah tipe khusus dari diagram status yang memperlihatkan

aliran dari suatu aktivitas ke aktivitas lainnya dalam suatu sistem

(Prabowo, 2013).

(4) Diagram kelas. Bersifat statis. Diagram ini memperlihatkan himpunan

kelas - kelas, antarmuka - antarmuka, kolaborasi - kolaborasi, serta relasi -

relasi (Prabowo, 2013).

Simbol - simbol yang digunakan dalam pembuatan diagram - diagram di

atas dideskripsikan pada tabel di bawah ini :

Tabel 2.3 Use Case Diagram

Notasi Keterangan Simbol

Actor

Pengguna sistem atau yang

berinteraksi langsung dengan sistem,

bisa manusia, aplikasi, ataupun objek

lain

Use Case

Digambarkan dengan lingkaran elips

dengan nama use case nya tertulis di

tengah lingkaran

Assocation

Digambarkan dengan sebuah garis

yang berfungsi menghubungkan actor

dengan use case.

Sumber : Jurnal Unikom

Page 43: untuk memenuhi sebagian persyaratan mencapai derajat

24

Tabel 2.4 Activity Diagram

Sumber : Jurnal Unikom

Notasi Keterangan Simbol

Initial State Titik awal untuk

memulai suatu aktivitas

Final State Titik akhir untuk

mengakhiri suatu

aktivitas

Activity Menandakan sebuah

aktivitas

Decision Pilihan untuk

pengambilan

keputusan

Fork/ Join Menunjukkan

kegiatan

menggabungkan dua

panel activity menjadi

satu atau satu panel

activity menjadi dua

Send Tanda pengiriman

Receive Tanda penerimaan

Control Flow Arus aktivitas

Page 44: untuk memenuhi sebagian persyaratan mencapai derajat

25

Tabel 2.5 Sequence Diagram

Notasi Keterangan Simbol

Object Object adalah instance

dari sebuah class yang

dituliskan tersusun secara

horizontal diikuti lifeline

Activation Indikasi dari sebuah

objek yang melakukan

suatu aksi

Lifeline Indikasi keberadaan

sebuah objek dalam basis

waktu

Message Indikasi untuk

komunikasi antar object

Self-Message Komunikasi kembali

kedalam object itu sendiri

Sumber : Jurnal Unikom

Object1

Page 45: untuk memenuhi sebagian persyaratan mencapai derajat

26

Tabel 2.6 Class Diagram

Notasi Keterangan Simbol

Class Object adalah instance

dari sebuah class yang

dituliskan tersusun secara

horizontal diikuti lifeline

Association Indikasi dari sebuah

objek yang melakukan

suatu aksi

Dependency Indikasi keberadaan

sebuah objek dalam basis

waktu

Generalization Indikasi untuk

komunikasi antar object

Sumber : Jurnal Unikom

2.7 Hypertext Prepocessor (PHP)

PHP merupakan akronim dari PHP yaitu Hypertext Preprocessor. PHP

merupakan bahasa pemrograman berbasis web yang sudah sering digunakan.

Terdapat perbedaan antara web yang menggunakan PHP dan web yang hanya

sekedar menggunakan HTML saja. Hal tersebut dapat dilihat pada proses saat web

server memenuhi permintaan client untuk menampilkan halaman web. Pada

halaman web yang hanya menggunakan HTML, server langsung mengirimkan

halaman yang diminta oleh client dalam bentuk script HTML. Sedangkan pada

web yang menggunakan PHP sebelum server mengirimkan script HTML kepada

client, server membaca terlebih dahulu script PHP yang ada pada server tersebut

Page 46: untuk memenuhi sebagian persyaratan mencapai derajat

27

kemudian mengirimkan hasil dari script PHP tersebut kepada client berupa

HTML (Kadir, 2007).

1. Kelebihan PHP

Bahasa pemrograman PHP adalah sebuah bahasa script yang tidak

melakukan sebuah kompilasi dalam penggunaanya.

Web server yang mendukung PHP dapat ditemukan diberbagai macam

web server.

Dalam sisi pengembangan lebih mudah

Dalam sisi pemahaman, PHP adalah bahasa scripting yang mudah

digunakan.

PHP dapat membuat aplikasi di desktop, dan mendukung banyak

(Database).

2. Kelemahan PHP

PHP tidak mengenal package.

Jika tidak encoding, maka kode PHP dapat dibaca semua orang. dan

untuk meng encoding diperlukan tool berbayar.

2.8 Hyper Text Markup Language (HTML)

HTML (Hyper Text Markup Language) merupakan bahasa standart yang

dapat digunakan untuk menampilkan halaman web [15].

Kegunaanya yaitu :

Mengatur tampilan dari halaman web dan isinya..

Membuat tabel dalam halaman web.

Mempublikasikan halaman web secara online..

Membuat form yang bisa di gunakan untuk menangani registrasi dan

transaksi via web.

Menambahkan objek-objek seperti citra, audio, video, animasi, java applet

dalam halaman web.

Menampilkan area gambar (canvas) di browser.

Page 47: untuk memenuhi sebagian persyaratan mencapai derajat

28

2.9 Diagnosa

Diagnosa atau diagnosis dalam kamus besar bahasa Indonesia adalah

suatu penyakit dengan meneliti (memeriksa) gejala-gejalanya (Sugono,

2008:350)

2.10 Penyakit

Penyakit adalah suatu keadaaan abnormal dari tubuh atau pikiran yang

menyebabkan ketidaknyamanan, disfungsi atau kesukaran terhadap orang yang

dipengaruhinya.

2.11 Database dan MySQL

Database adalah kumpulan data yang tersusun secara sistematis sehingga

dapat memudahkan pengguna dalam mengakses dan mengelola serta untuk

mendapatkan informasi yang efektif dan efisien. Database dapat berdiri sendiri

dan dapat juga digabung menjadi satu kesatuan, penggabungan antar database

disebut dengan relasi, sebagai contoh data costumer digabung dengan data order.

Untuk menggabungkan data harus ada penghubung yang disebut dengan indeks.

Syarat dari indeks adalah tidak boleh ada data yang sama dan data yang digabung

masing-masing harus mempunyai indeks yang sama.

DBMS (Database Management System) merupakan software yang banyak

digunakan dalam pengolahan data. Contoh manajemen database adalah sistem

manajemen database relasi. Komponen dalam sistem manajemen database relasi

adalah sebagai berikut :

1. Database sebagai tempat untuk menyimpan data yang terstruktur, data

tersimpan dalam tabel, tabel tersebut terdiri dari baris dan kolom yang di

dalamnya terdapat field dan record.

2. System management adalah software yang digunakan untuk mengelola

database tersebut.

Relasi adalah hubungan antara tabel- tabel yang ada di dalam database.

Fungsi MySQL dapat dikatakan sebagai interpreter query, karena setiap

Page 48: untuk memenuhi sebagian persyaratan mencapai derajat

29

menggunakan query SQL (perintah SQL) harus meletakkannya di dalam fungsi

ini. Dengan kata lain, SQL tidak dapat dijadikan tanpa adanya fungsi MySQL.

MySQL termasuk jenis relational database management system (RDBMS).

Sehingga istilah seperti tabel, baris dan kolom tetap digunakan dalam MySQL.

Pada MySQL, SQL merupakan kependekan Structured Query Language. SQL

digunakan untuk berkomunikasi dengan sebuah database. SQL adalah bahasa

yang meliputi perintah-perintah untuk menyimpan, menerima, memelihara, dan

mengatur akses ke database serta digunakan untuk memanipulasi dan

menampilkan data dari database (Puspitasari, 2011).

DBMS mempunyai kamampuan seperti:

a) Membuat, menambah, menghapus, dan memodifikasi basis data

b) Pada beberapa DBMS pengelolanya berbasis windows (berbentuk jendela-

jendela) sehingga lebih mudah digunakan

c) Tidak semua orang bisa mengakses basis data yang ada sehingga dapat

memberikan keamanan

d) Kapabilitas berkomunikasi dengan program aplikasi yang lain. Misalnya

dimungkinkan untuk mengakses basis data MySQL, menggunakan aplikasi

yang dibuat menggunakan PHP

e) Kemampuan pengaksesan melalui komunikasi antar komputer (client

server)

1. Kelebihan MySQL

a) Gratis dan handal

b) Selalu di-update

c) Banyak forum yang memfasilitasi para pengguna jika memiliki kendala

d) MySQL juga menjadi DBMS yang sering dibundling dengan web server

sehingga proses instalasinya jadi lebih mudah

e) Bisa mendeteksi kesalahan pesan terhadap client dengan menggunakan

beberapa bahasa walaupun bahasa indonesia belum termasuk didalam

MySQL.

Page 49: untuk memenuhi sebagian persyaratan mencapai derajat

30

f) Dapat digunakan dan dijalankan dengan spesifikasi hardware yang relatif

rendah karena MySQL penggunaan databasenya lebih hemat resource

memory (dibandingkan dengan database lain).

2. Kelemahan MySQL

a) Tidak menerapkan konsep Technology Cluster Server sehingga

mempunyai keterbatasan kinerja dalam server ketika data yang telah

disimpan melebihi batas maksimal

b) Fitur-fitur belum lengkap dan belum sesuai standar

c) Dari segi keamanan masih terlalu sederhana bagi sebuah SQL Engine

2.12 PHPMyAdmin

Sibero (2011) “phpMyAdmin adalah aplikasi yang dibuat oleh

PHPMyAdmin.net. PHPMyAdmin digunakan untuk administrasi database

MySql”. Program ini digunakan untuk mengakses database MySql.Perintah untuk

membuat table dapat menggunakan form yang sudah tersedia pada PHPMyAdmin

atau dapat langsung menuliskan script pada menu SQL. PHPMyAdmin dijalankan

dengan mengetik http://localhost/PHPmyadmin web browser padalocallhost.

Menurut Arief, M.Rudyanto (2011). PHPMyAdmin adalah salah satu aplikasi GUI

(Graphical User Interface) yang digunakan untuk mengelola database MySql”.

Menurut Kurniawan (2008:8) “PHPMyAdmin adalah halaman yang terdapat

pada web server”. Fungsi dari hal aman ini adalah sebagai pengendali database

MySql menggunakan web server. XAMPP adalah perangkat lunak bebas, yang

mendukung banyak sistem operasi, merupakan kompilasi dari beberapa program.

Fungsinya adalah sebagai server yang berdiri sendiri (localhost), yang terdiri atas

program Apache HTTP Server, MySQL database, dan penerjemah bahasa yang

ditulis dengan Bahasa pemrograman PHP dan Perl. Nama XAMPP merupakan

singkatan dari X (empat sistem operasi apapun), Apache, MySQL, PHP dan Perl.

Program ini tersedia dalam GNU General Public License dan bebas, merupakan

web server yang mudah digunakan yang dapat melayani tampilan halaman web

Page 50: untuk memenuhi sebagian persyaratan mencapai derajat

31

yang dinamis. Untuk mendapatkanya dapat mendownload langsung dari web

resminya.

2.13 Localhost

Localhost merupakan istilah dalam computer jaringan yang berarti

komputer ini. localhost adalah nama standar yang diberikan sebagai alamat

loopback network interface. Localhost selalu menerjemahkan loopback ip

address 127.0.0.1 dalam IPv4, atau dalam IPv6. Localhost digunakan untuk

mengantarkan web browser pada HTTP server yang terinstall di komputer lokal.

Alamat http://localhost akan menampilkan website lokal pada komputer yang

bersangkutan.

Jadi, ketika computer 1 sebagai localserver dan lainnya sebagai client,

kemudian menghostingkan web didalamnya (localhost) untuk dijadikan tempat

membangun website sementara dan kemudian dihostingkan secara online ke

internet.

Dengan demikian menjadikan komputer kita sebagai localserver, kita

dapat bekerja secara offline tanpa harus takut menghadapi masalah biaya,

waktu,dan kenyamanan.

2.14 Pengujian Perangkat Lunak

Pengujian perangkat lunak adalah elemen kritis dari jaminan kualitas

perangkat lunak dan merepresentasikan kajian pokok dari spesifikasi, desain, dan

pengkodean. Sejumlah aturan yang berfungsi sebagai sasaran pengujian pada

perangkat lunak adalah (Sukamto, 2009) :

1) Pengujian adalah proses eksekusi suatu program dengan maksud menemukan

kesalahan.

2) Test case yang baik adalah test case yang memiliki probabilitas tinggi untuk

menemukan kesalahan yang belum pernah ditemukan sebelumnya.

3) Pengujian yang sukses adalah pengujian yang mengungkap semua kesalahan

yang belum pernah ditemukan sebelumnya.

Page 51: untuk memenuhi sebagian persyaratan mencapai derajat

32

Karakteristik umum dari pengujian perangkat lunak adalah sebagai berikut

(Sukamto, 2009) :

1) Pengujian dimulai pada level modul dan bekerja keluar kearah integrasi pada

sistem berbasiskan komputer.

2) Teknik pengujian yang berbeda sesuai dengan poin-poin yang berbeda pada

waktunya.

3) Pengujian diadakan oleh software developer dan untuk proyek yang besar

oleh group testing yang independent.

4) Testing dan Debugging adalah aktivitas yang berbeda tetapi debugging harus

diakomodasikan pada setiap strategi testing.

Metode pengujian perangkat lunak ada 3 jenis, yaitu (Sukamto, 2009) :

1) White Box/Glass Box -pengujian operasi

2) Black Box -untuk menguji sistem

3) Use case-untuk membuat input dalam perancangan black box dan pengujian

statebased

2.1.13 Black Box Testing

Pengujian menggunakan sekumpulan aktifitas validasi, dengan

pendekatan black box testing. Menurut Shalahuddin dan Rosa (2011), black box

testing adalah menguji perangkat lunak dari segi spesifikasi fungsional tanpa

menguji desain dan kode program. Pengujian dimaksudkan untuk mengetahui

apakah fungsi-fungsi, masukan, dan keluaran dari perangkat lunak sesuai dengan

spesifikasi yang dibutuhkan. Pengujian kotak hitam dilakukan dengan membuat

kasus uji yang bersifat mencoba semua fungsi dengan memakai perangkat lunak

apakahsesuai dengan spesifikasi yang dibutuhkan. Kasus uji yang dibuat untuk

melakukan pengujian black box testing harus dibuat dengan kasus benar dan

kasus salah.

Menurut Pressman (2010), black box testing juga disebut pengujian

tingkah laku, memusat pada kebutuhan fungsional perangkat lunak. Teknik

pengujian black box memungkinkan memperoleh serangkaian kondisi masukan

Page 52: untuk memenuhi sebagian persyaratan mencapai derajat

33

yang sepenuhnya menggunakan semua persyaratan fungsional untuk suatu

program. Beberapa jenis kesalahan yang dapat diidentifikasi adalah fungsi tidak

benar atau hilang, kesalahan antar muka, kesalahan pada struktur data

(pengaksesan basis data), kesalahan performasi, kesalahan inisialisasi dan akhir

program.

2.16 Tinjauan Objek Penelitian

Penulis meninjau penelitian ini dengan melihat hasil dari penelitian -

penelitian sebelumnya yang pernah dilakukan. Ini dilakukan untuk mencari

metode serta cara yang lebih tepat. Berikut ini hasil dari penelitian yang pernah

dilakukan sebelumnya menggunakan beberapa metode:

Penelitian sistem pakar juga dibuat oleh (Masykur, 2012) menggunakan

metode lain dengan judul ”Implementasi Sistem Pakar Diagnosis Penyakit

Diabetes Mellitus Menggunakan Metode Fuzzy Logic Berbasis Web”. Sistem

pakar fuzzy logic dapat diterapkan menggunakan aplikasi web karena dengan

aplikasi web bisa mudah digunakan oleh semua pihak tanpa batasan waktu.

Dengan digunakan aplikasi web, pengguna dapat dengan mudah dan cepat

mengakses sistem.

Penelitian sistem pakar lain juga dikemukakan oleh (Nurhasanah, 2010)

Metode yang digunakan dalam sistem pakar yang dikembangkan menggunakan

metode Backward Chaining. Dengan judul “Sistem Pakar Untuk Memprediksi

Awal Penyakit Gigi Dan Mulut Berbasis Web Dengan Metode Backward

Chaining”. Backward Chaining (Pelacakan ke belakang) adalah pencocokan

fakta atau pernyataan dimulai dari bagian sebelah kanan (THEN dulu). Dengan

kata lain, penalaran dimulai dari hipotesis terlebih dahulu, dan untuk menguji

kebenaran hipotesis tersebut, harus dicari fakta-fakta yang ada.

Adapun pengembang sistem pakar dengan metode yang lain (Khotimah,

2010) judul yang diangkat adalah “Sistem Pakar Troubleshooting Komputer

dengan metode Certainty Factor Menggunakan Probabilitas Bayesian”, untuk

mengukur tingkat kepastian dalam menganalisa suatu masalah. Aplikasi yang

dikembangkan berbasis desktop.

Page 53: untuk memenuhi sebagian persyaratan mencapai derajat

34

Dari ketiga penelitian di atas dapat disimpulkan sebagai berikut. Pada

penelitian yang pertama melakukan perancangan sistem pakar untuk diagnosa

penyakit diabetes melitus menggunakan metode fuzzy logic menggunakan sistem

berbasis web. Sedangkan penelitian yang ke dua Perancangan sistem pakar

mendiagnosa penyakit gigi dan mulut menggunakan metode Backward Chaining

berbasis web. Pada penelitian sistem pakar yang ke tiga mendiagnosa

Trobleshooting komputer menggunakan metode Certainty Factor dengan sistem

berbasis desktop.

Dari ketiga penelitian di atas peneliti mencoba mencari metode yang

belum digunakan oleh ketiga peneliti tersebut. Dan untuk masalah yang coba

diteliti sama dengan penelitian kedua (Nurhasanah, 2010) hanya saja peneliti coba

memfokuskan kepada penyakit gigi saja. Sedangkan untuk metode yang

digunakan, peneliti menggunakan metode Dempster Shafer berbeda dengan ketiga

metode yang digunakan di atas. Begitu juga dengan bahasa pemrograman peneliti

coba meggunakan pemrograman mobile Android sebagai alat implementasinya.

Studi literature dimaksudkan sebagai bahan pembanding penulis dalam

pengembangan aplikasi yang dibangun. Studi literature ini dilakukan dengan

mengumpulkan adata dari skirpsi atau jurnal hasil ppenelitian orang lain yang

berkesesuain dengan penelitian ini.

Table 2.7 Perbandingan Studi Literature

No

. Judul Penulis

Pebandingan

Studi Literatur Skripsi Penulis

1

Perancangan

sistem pakar

untuk

diagnosa

penyakit gigi

menggunakan

bahasa

pemogrmaran

Clips

I Nyoman

Kususma

Wardana

Penulis menggunakan

metode penalaran

forward chainiing dan

penelusuran generate

and test. Pada kasus

diagnosa belum dapat

belum dapat

menentukan diagnosa

banding, tapi diagnosa

banding ini dapat

ditemukan saat jalur

penelusuran generate

and test sudah terdefinisikan pada

Metode yang

digunakan penulis

dalam penalaran

adalah forward

chaining dan

penelusuran

dengan best first

search hal ini

memungkinkan

aplikasi data

diagnosa banding

tidak hanya satu

Page 54: untuk memenuhi sebagian persyaratan mencapai derajat

35

jalur penelusurannya

sementara, jika belum

akan ditemukan. Data

diagnosis yang sering

muncul di daerah tropis

khusunya Indonesia.

diagnosa tunggal.

Dan diagnosa

yang digunakan

yang digunakan

mempresentasika

n data dignosa

yang sering

muncul di daerah

tropis khususnya

Indonesia.

2

Sitem Pakar

penyakit gigi

menggunakan

metode

forward

chaining

Fetty Tri

Anggraen

y

Penulis menggunakan

metode penalaran

forward chaining pada

software delphi 7.0`

Tidak ditemukan pola

penelusuran data pada

penelitian ini.

Penelitian ini penelitian

ini. Penelitian ini juga

belum menghasilkan

diagnosa banding pada

hasil diagnosanya.

Penulis

menggunakan

media web

sehingga mampu

diaplikasikan

menggunakan

media

berteknologi

internet.

3

Pengembanga

n sistem pakar

pada

perangkat

mobile untuk

mendiagnosa

penyakit gigi

Bambang

Yuwono

Penulis menggunakan

metode penalaran

backward chaining

dengan metode

penelusuran depth first

search sudah

menggunakan teknologi

internet dan mobile

phone. Tapi hanya

mampu mampu

menampilkan satu

diagnosa banding

sesuai dengan karekter

pola penelusuran depth

firsh search.

Penulis

menggunakan

media forward

chaining dan best

first search

sebagai penambah

kekurangan pada

penelitian

Bambang

Yuwono.

Page 55: untuk memenuhi sebagian persyaratan mencapai derajat

36

BAB III

ANALISA MASALAH

3.1 Analisa Objek Penelitian

3.1.1 Sejarah Praktek Dokter Gigi Drg. Priska Widhi Anindya Santi

Praktek pengobatan Dokter gigi Drg. Priska merupakan praktek dokter

gigi rumahan, membuka praktek pribadi setelah menyelesaikan pendidikan

fakultas kedokteran gigi di Universitas Trisakti. merupakan lulusan fakultas

kedokteran gigi di Universitas Trisakti pada tahun 2012, Setelah menjalani

pendidikan selama 4 tahun untuk mendapatkan gelar Sarjana Kedokteran Gigi

(S.KG). Dan pernah mengikuti masa magang/ kepaniteraan (ko-ass) di Rumah

Sakit Mitra Keluarga selama kurang lebih 2 tahun untuk mendapatkan gelar

dokter gigi (Drg).

Untuk megimplementasikan ilmunya dibidang kedokteran gigi, maka

saya bersama rekan Drg. Melvin Leonardo membuka praktek Dokter gigi pribadi

di sebuah gedung yang beralamat Jl.Anggrek Raya No. 10 Jababeka2, Cikarang.

Adapun pembukaan praktek pertama kali pada 17 November 2013 sebagai awal

berdirinya Praktek Dokter Gigi Drg. Priska Widhi Anindya santi. Dan tidak

menutup kemungkinan untuk menjadikan Praktek Dokter Gigi ini sebagai

KLINIK apabila memang sudah memenuhi persyaratan, untuk menjadikan

praktek ini menuju kearah yang lebih baik lagi.

3.1.2 Visi dan Misi

Visi

Memberikan pelayanan terbaik dan professional untuk kesehatan gigi dan mulut

anda.

Page 56: untuk memenuhi sebagian persyaratan mencapai derajat

37

Dokter Penanggung Jawab

Drg. Priska Widhi Anindya

Pelaksana Medis

1.Drg. Priska Widhi Anindya

2.Drg. Melvin Leonardo

Administrasi

Nita sari

Pelaksana Farmasi

Wulandari

Misi

1. Memberikan pelayanan terbaik kepada semua lapisan masyarakat.

2. Menyediakan fasilitas yang baik untuk menunjang kinerja agar mendapatkan

hasil yang optimal.

3. Memberikan informasi seputar gigi kepada masyarakat.

3.1.3 Struktur Organisasi

Struktur organisasi merupakan kerangka dan susunan terwujudnya pola

tetap hubungan-hubungan antara fungsi-fungsi, bagian-bagian atau posisi-posisi

maupun orang-orang yang menunjukan kedudukan, tugas, tugas, wewenang dan

tanggung jawab yang berbeda-beda dalam suatu organisasi akan mempunyai suatu

peranan dan fungsi yang berbeda dalam instansi-instansi maupun perusahaan-

perusahan kecil maupun beasr.

Gambar 3.1 Struktur organisasi Praktek Drg. Priska Widhi Anindya santi

Sumber : Struktur Organisasi Praktek Drg. Priska Widhi Anindya santi

Page 57: untuk memenuhi sebagian persyaratan mencapai derajat

38

3.2 Analisa Sistem Berjalan

Sistem yang berjalan saat ini masih bersifat manual, digambarkan dengan diagram

use case di bawah ini :

Gambar 3.2 Use Case Sistem Praktek Drg. Priska Widhi Anindya santi

Pasien

Mendaftarkan diri

Catat data pasien

Menyampaikan gejala

Periksa kondisi pasien

Dokter

Administrasi

Diagnosa penyakit

Catat hasil diagnosa & pengobatan

Use Case Sistem Praktek Drg. Priska Widhi Anindya Santi

Page 58: untuk memenuhi sebagian persyaratan mencapai derajat

39

Dari uses case diatas dapat dijelaskan sebagai berikut :

Tabel 3.1 Use Case Sistem Berjalan

Nama Use Case

Use Case Sistem Berjalan

Aksi pasien Aksi Sistem

1. Daftar ke bagian administrasi

2. Admin mencatat data pasien dan

memberikannya ke dokter

3. Admin memanggil pasien

berdasarkan urutan

4. Pasien konsultasi dengan dokter

perihal keluhanya

5. Dokter memeriksa kondisi

pasien

6. Dokter mendiagnosa penyakit

pasien

7. Dokter mencatat hasil diagnosa

dan pengobatanya

3.3 Desain Penelitian

Desain penelitian yaitu gambaran tahapan yang akan dilakukan peneliti

untuk mempermudah dalam melakukan penelitian. Berikut adalah tahapan

penelitian yang akan dilakukan.

Page 59: untuk memenuhi sebagian persyaratan mencapai derajat

40

Gambar 3.3 Desain Penelitian

Penjelasan desain penelitian :

1. Proses pertama

a. Menganalisis permasalahan kesehatan gigi dan mulut berdasarkan fakta-

fakta yang ada

1. Analisis permasalahan

Rumusan Masalah

1. Studi Literatur

2. Menentukan lokasi penelitian

3. Mempersiapkan alat dan bahan penelitian

4. Wawancara

5. Mengumpulkan data penelitian

Hasil studi literatur dan

data penelitian

1. Pengujian implementasi metode dempster shafer

2. Pengujian perangkat lunak

3. Pengujian tingkat akurasi hasil diagnosa

4. Menganalisa hasil pengujian

5. Pengambilan kesempulan

6. Menyertakan saran

Pengujian Penelitian

Analisis Hasil Uji

2. Menentukan kebutuhan data penelitian & faktor

apa saya yang akan diangkat

Mengimplementasikan metode Demper shafer

Page 60: untuk memenuhi sebagian persyaratan mencapai derajat

41

b. Menentukan kebutuhan data penelitian

Menentukan kebutuhan data yang akan digunakan dalam penelitian seperti

data jenis penyakit, data gejala, data solusi dari penyakit, data pasien dan

menentukan faktor apa saja yang harus diperhatian pada permasalahan yang

akan diangkat di penelitian

Output dari proses pertama adalah rumusan masalah penelitian

2. Proses ke-dua

a. Studi literatur

Proses pembelajaran mengenai literatur-literatur yang mendukung

pelaksanaan penelitan untuk memahami dan memperdalam teori maupun

metode yang akan digunakan yaitu metode dempster shafer. Proses

pembelajaran dilakukan dengan mencari teori dan referensi dari textbook,

jurnal, dan sumber lainnya yang berkaitan dengan penyakit gigi dan mulut

dan metode yang akan digunakan

b. Menentukan lokasi penelitian

Untuk lokasi penelitian berada di Rumah Sakit Umum Daerah Soreang, Jl.

Alun-Alun Utara No.1, Soreang, Bandung, Jawa Barat.

c. Mempersiapkan alat dan bahan penelitian

Mempersiapkan perangkat yang akan digunakan untuk penelitian dan bahan

penelitian yaitu data-data yang dibutuhkan

d. Wawancara

Wawancara dilakukan untuk mendapatkan informasi tentang berbagai

penyakit gigi dan mulut beserta gejalanya dan juga solusi untuk penanganan

penyakit tersebut. Wawancara juga dilakukan untuk mengetahui nilai MB

dan nilai MD setiap gejala dari penyakit gigi dan mulut. Nilai tersebut akan

digunakan sebagai parameter metode dempster shafer untuk melakukan

perhitungan kemungkinan penyakit.

e. Mengumpulkan data penelitian

Data-data yang sudah diperoleh dari semua proses diatas dikumpulkan

dan diolah agar dapat memenuhi kebutuhan penelitian.

Page 61: untuk memenuhi sebagian persyaratan mencapai derajat

42

Output dari proses ke-dua adalah hasil studi literatur mengenai metode-

metode yang akan digunakan untuk menyelesaikan permasalahan yaitu

metode Dempter Shafer. Selain itu output lain juga berupa hasil wawancara

pakar mengenai data penyakit gigi dan mulut beserta gejala dari setiap

penyakitnya dan data nilai MB dan nilai MD setiap gejalanya, solusi dari

setiap penyakit, dan penjelasan dari setiap penyakit yang sudah diolah dan

siap digunakan untuk proses selanjutnya

3. Proses selanjutnya adalah merangkai data-data dan teori yang sudah didapatkan

dari proses wawancara dan studi literatur untuk membangun sebuah perangkat

lunak. Pada proses ini metode Dempter Shafer diimplementasikan ke dalam

perangkat dan dibangunlah sebuah aplikasi sistem pakar untuk mendiagnosis

penyakit gigi dan mulut. Perangkat lunak dibangun dengan menggunakan

metode Waterfall dengan tahapan pengumpulan kebutuhan sistem,

pembentukan desain & arsitektur sistem, mengimplementasikan desain sistem

yang sudah dibuat menjadi unit program, pengintegrasian unit program dan

pengujian setiap unitnya, dan terakhir instalasi dan pemeliharaan sistem.

Output dari tahap ini adalah aplikasi Sistem Pakar diagnosis penyakit Gigi dan

Mulut (SIPAGIMU).

4. Pengujian penelitian

Setelah perangkat lunak berhasil dibangun, tahap selanjutnya adalah pengujian

penelitian penerapan metode certainty factor dan metode rulebased reasoning

ke dalam sistem dan pengujian perangkat lunak. Selain itu diuji juga seberapa

akurat hasil diagnosis sistem dibandingkan dengan diagnosis yang dilakukan

oleh pakar`

1. Tahap terakhir adalah tahap analisis hasil uji. Pada tahap analisis hasil uji akan

dilihat bagaimana hasil dari pengujian penelitian, ada berapa sample data yang

berhasil dan ada berapa sample data yang gagal. Setelah itu akan ditarik

kesimpulan dari penelitian yang telah dilakukan dan menyertakan saran untuk

penelitian kedepannya.

Page 62: untuk memenuhi sebagian persyaratan mencapai derajat

43

3.4 Metode Penelitian

Metode penelitian ini dibagi menjadi dua, yaitu metode pengumpulan data dan

metode pengembangan perangkat lunak.

3.4.1 Metode Pengumpulan Data

Dalam penelitian ini proses pengumpulan data dilakukan dengan cara

sebagai berikut:

a. Wawancara

Wawancara dilakukan dengan melakukan tanya jawab dengan pakar yaitu

dokter gigi untuk mendapatkan informasi yang dibutuhkan dan data yang

akurat mengenai penyakit-penyakit gigi dan mulut. Kemudian pakar

memberikan nilai MB dan MD pada setiap gejala penyakit gigi dan mulut.

b. Studi literatur

Dengan melakukan studi mengenai kecerdasan buatan, sistem pakar, metode

certainty factor, metode rule-based reasoning dan penyakit gigi dan mulut

melalui literatur seperti buku, jurnal, dan sumber ilmiah lain.

3.4.2 Metode Pengembangan Perangkat Lunak

Pembangunan perangkat lunak dalam penelitian ini menggunakan model

waterfall. Model waterfall adalah sebuah contoh dari proses perencanaan, dimana

semua proses kegiatan harus terlebih dahulu direncanakan dan dijadwalkan

sebelum dikerjakan (Sommerville, 2011). Dalam model waterfall Sommerville

terdapat kemungkinan untuk kembali ke tahap sebelumnya apabila terjadi

kesalahan atau perbaikan, dimana alur prosesnya seperti pada gambar berikut ini.

Gambar 3.4 Model Waterfall (Sommerville, 2011)

Page 63: untuk memenuhi sebagian persyaratan mencapai derajat

44

1. Requirements definition (Definisi kebutuhan)

Mengumpulkan kebutuhan, penetapan fitur, kendala dan tujuan sistem melalui

konsultasi dengan pengguna sistem. Semua hal tersebut akan ditetapkan secara

rinci dan berfungsi sebagai spesifikasi sistem.

2. System and software design (Desain sistem dan perangkat lunak)

Dalam tahapan ini akan dibentuk suatu arsitektur sistem berdasarkan

persyaratan yang telah ditetapkan. Dan juga mengidentifikasi dan

menggambarkan abstraksi dasar sistem perangkat lunak dan hubungan-

hubungannya.

3. Implementation and unit testing (Tes implementasi dan unit)

Hasil dari desain perangkat lunak akan direalisasikan sebagai satu set program

atau unit program. Setiap unit akan diuji apakah sudah memenuhi

spesifikasinya.

4. Integration and unit testing (Tes integrasi dan unit)

Setiap unit program akan diintegrasikan satu sama lain dan diuji sebagai satu

sistem yang utuh untuk memastikan sistem sudah memenuhi persyaratan yang

ada. Setelah itu sistem akan dikirim ke pengguna sistem.

5. Operation and maintenance (Operasi dan maintenance)

Dalam Operation and maintenance, sistem diinstal dan mulai digunakan. Selain

itu juga memperbaiki error yang tidak ditemukan pada tahap pembuatan.

Dalam tahap ini juga dilakukan pemeliharaan software serta pengembangan

sistem seperti penambahan fitur dan fungsi bar.

3.5 Analisis Sistem

Dalam membangun sebuah aplikasi untuk mengidentifikasi penyebab

penyakit gigi dengan menggunakan metode Dempster-Shafer berbasis web

dilakukan beberapa tahap analisis yaitu :

1. Menentukan masalah yang akan dibangun untuk sebuah aplikasi. Sistem yang

akan dibangun merupakan sebuah aplikasi untuk mengidentifikasi penyebab

penyakit gigi dengan menggunakan metode Dempster-Shafer berbasis web.

Page 64: untuk memenuhi sebagian persyaratan mencapai derajat

45

2. Mengumpulkan data yang diperlukan untuk membangun sistem, yaitu berupa

informasi tentang gejala, penyebab, dan jenis penyakit melalui studi literatur

dan observasi yang digunakan sebagai base knowledge.

3. Mempresentasikan pengetahuan ke dalam tabel gejala yang telah dianalisis,

penelusuran gejala dan jenis penyebab penyakit.

4. Usulan sistem yang akan dibuat.

3.5.1 Sumber Informasi

Data mengenai penyebab penyakit pada gigi yaitu pengertian jenis

penyakit, gejala, penyebab serta penanganannya yang didapat dari buku, artikel,

dan situs internet.

3.5.2 Identifikasi Masalah

Langkah pertama dalam mengembangkan aplikasi adalah

mengidentifikasikan masalah yang akan dikaji, dalam hal ini adalah dengan

mengidentifikasikan permasalahan yang akan dibuat terlebih dahulu, adapun

masalah-masalah yang akan diambil dalam aplikasi untuk mengidentifikasi

penyebab penyakit pada ikan air tawar.

3.5.3 Analisis data Penyebab Penyakit dan Gejala

Keberhasilan suatu aplikasi terletak pada pengetahuan dan bagaimana

mengolah pengetahuan tersebut agar dapat ditarik suatu kesimpulan. Pengetahuan

yang diperoleh dari hasil wawancara dan analisa lewat buku dikonversi kedalam

sebuah tabel penyakit dan gejala guna mempermudah proses pencarian solusi.

Tabel jenis penyebab penyakit dan gejala ini digunakan sebagai pola pencocokan

informasi yang dimasukan oleh pemakai dan basis pengetahuan.

Pada tabel jenis penyebab penyakit dan gejala terdapat 6 jenis penyebab

penyakit yang ditunjukkan oleh PI-1, PI-2,...,PI-6 dan 21 gejala yang ditunjukkan

oleh G-1,G-2,...,G-21. Dari 21 jenis penyebab penyakit disusun sebagai

pernyataan dan 21 gejala disusun sebagai kesimpulan. Gejala ini merupakan basis

pengetahuan untuk membuat suatu kesimpulan yang menjadi goal. Berikut ini

Page 65: untuk memenuhi sebagian persyaratan mencapai derajat

46

adalah tabel jenis penyebab penyakit dan gejala pada Tabel 3.1 yaitu tabel gejala

dan jenis penyebab penyakit pada ikan air tawar.

Tabel 3.2 Kode Penyakit Gigi

KODE PENYAKIT

P001 Caries/Gigi berlubang

P002 Abses gigi

P003 Gingivitis (Gusi Bengkak)

P004 Pulpitis(radang pulpa gigi)

P005 Gigi pernah retak,copot,goyah

P006 malocclusion

Tabel 3.3 Kode Gejala Penyakit Gigi

KODE GEJALA

G001 Timbul bercak coklat atau putih digigi

G002 Muncul lubang cokelat

G003 Terasa ngilu saat makan dan minum

G004 Rasa sakit yang kadang-kadang dibagian gigi

G005 Sakit gigi berdenyut

G006 Sakit saat mengunyah

G007 pembengkakan kelenjar getah bening di leher

G008 Demam

G009 Mulut kering

G010 Gusi tampak merah

G011 Gusi membengkak

G012 Gusi mudah berdarah

G013 Rasa sakit yang timbul spontan dalam waktu lama

G014 Rasa sakit bila terkena rangsangan panas,dingin atau manis

G015 Rasa sakit kambuhan berbulan - bulan

G016 Gigi memiliki patahan tidak lengkap

G017 Nyeri singkat dan tajam saat makan yang dingin

G018 Rasa tidak nyaman saat mengunyah

G019 Posisi gigi bengkok

G020 Posisi gigi ramai

G021 Gigi menonjol

Page 66: untuk memenuhi sebagian persyaratan mencapai derajat

47

Tabel 3.4 Gejala Penyakit Gigi

Tabel 3.5 Contoh Tabel Perhitungan Gejala Penyakit Gigi

G001 G002 G003 G004 G005 G006 G007 G008 G009 G010 G011 G012 G013 G014 G015 G016 G017 G018 G019 G020 G021

1 Caries/Gigi berlubang √ 0.8 √ 0.9 √ 0.7 √ 0.5

3 Abses gigi √ 0.7 √ 0.6 √ 0.9 √ 0.8

4 Gingivitis (Gusi Bengkak) √ 0.6 √ 0.8 √ 0.9 √ 0.7

5 Pulpitis(radang pulpa gigi) √ 0.8 √ 0.7 √ 0.9

6 Gigi pernah retak,copot,goyah √ 0.5 √ 0.9 √ 0.4

7 malocclusion √ 0.6 √ 0.8 √ 0.7 √ 0.9

Tabel Gejala Penyakit Gigi

No PenyakitGejala

1 2 3 4 5 6 7 8 9 10 11 12

No Penyakittimbul bercak

coklat atau

putih digigi

muncul

lubang

cokelat

Terasa ngilu

saat makan

dan minum

Rasa sakit

yang kadang-

kadang

dibagian gigi

Sakit gigi

berdenyut

Sakit saat

mengunyah

Gusi terasa

gataldemam Gigi goyang

Gusi tampak

merah

Gusi

membengkak

Gusi mudah

berdarah

1 Caries/Gigi berlubang 1 (0,2) 1(0,3) 1(0,6) 1(0,5) 1(0,4)

2 Abses gigi 2(0,8) 2(0,7) 2(0,4) 2(0,5) 2(0,6)

3 Gingivitis (Gusi Bengkak) 3(0,3) 3(0,8) 3(0,7) 3(0,9)

4 Pulpitis(radang pulpa gigi)

5 Periodontitis 5(0,5) 5(0,9)

6 malocclusion

13 14 15 16 17 18 19 20 21

No Penyakit

Rasa sakit

yang timbul

spontan

dalam waktu

lama

Rasa sakit

bila terkena

rangsangan

panas,dingin

atau manis

Rasa sakit

kambuhan

berbulan -

bulan

Gigi memiliki

patahan tidak

lengkap

Nyeri singkat

dan tajam

saat makan

yang dingin

Rasa tidak

nyaman saat

mengunyah

Posisi gigi

bengkok

Posisi gigi

ramai /

berjejal

Gigi menonjol

1 Caries/Gigi berlubang 1 (0,9) 1 (0,8) 1 (0,1) 1 (0,7)

2 Abses gigi 2(0,9)

3 Gingivitis (Gusi Bengkak)

4 Pulpitis(radang pulpa gigi) 4(0,9) 4(0,8) 4(0,5) 4(0,1)

5 Periodontitis

6 malocclusion 6(0,7) 6(0,9) 6(0,8) 6(0,1)

ket :

angka di kolom penanda gejala penyakit yang di derita

angka di dalam kurung merupakan presentasi gejala dari penyakit tersebut

Tabel Gejala Penyakit Gigi

Dibuat Diperiksa

Page 67: untuk memenuhi sebagian persyaratan mencapai derajat

48

3.5.4 Identifikasi Input

Untuk proses mengidentifikasikan keluaran yang diperlukan adalah

melakukan pengumpulan data atau informasi yang mendukung dalam pembuatan

aplikasi untuk memecahkan masalah dan selanjutnya akan diproses oleh aplikasi.

Aplikasi akan mengajukan gejala-gejala penyebab penyakit yang timbul pada gigi,

gejala tersebut akan disimpan sebagai rule dalam bentuk database, dimana gejala

ini adalah salah satu cara sistem mengumpulkan informasi tentang suatu masalah

yang ingin dipecahkan.

3.5.5 Identifikasi Output

Setelah aplikasi menerima masukan dari pengguna melalui gejala yang

diajukan oleh aplikasi, maka aplikasi akan memberikan kesimpulan dari gejala

yang dijawab tersebut. Untuk kesimpulan dari gejala yang benar, maka aplikasi

akan memberikan informasi indentifikasi, dan penyebab.

3.5.6 Analisis Kebutuhan Non Fungsional

Kebutuhan non fungsional adalah usulan yang direkomendasikan kepada

pengguna agar aplikasi yang akan dibangun menjadi user friendly dan perangkat

kerasnya yang mendukung secara maksimal terhadap kinerja perangkat lunak.

3.5.6.1 Analisis Pengguna

Penyuluh yang menjadi Pakar yaitu :

Nama : Drg. Priska Widhi Anindya Santi

Jabatan : Peneliti Penyakit Gigi

Alamat : Jl.Anggrek Raya No. 10 Jababeka2, Cikarang

Pengalaman menggunakan Komputer : Windows 98, Windows 2000, Windows XP,

Windows vista.

Software yang pernah atau sering digunakan : Microsoft Office 2003, 2007.

3.5.6.2 Analisis Perangkat Keras

Perangkat keras minimum yang direkomendasikan untuk menjalankan aplikasi ini

adalah sebagai berikut :

Page 68: untuk memenuhi sebagian persyaratan mencapai derajat

49

Processor : Dengan kecepatan 2.0 GHz

Kapasitas Harddisk : 20 GB

RAM : 256 MB

VGA Card : 64 MB

Monitor

Mouse

Keyboard

3.5.6.3 Analisis Perangkat Lunak

Pemodelan Analisis Perangkat lunak yang digunakan adalah sistem operasi

Microsoft windows XP Professional, Bahasa Pemrogramannya menggunakan

PHP dengan toolnya Macromedia dreamweaver 8, serta menggunakan

databasenya yaitu MySQL.

3.5.6.4 Analisis Basis Data

Entity Relational Diagram (ERD) merupakan cara untuk

mengorganisasikan data, dimana diagram ini akan memperlihatkan hubungan

entitas yang terdapat dalam sistem. ERD yang diusulkan untuk sistem yang akan

dibangun dapat dilihat pada gambar 3.1 dibawah ini.

Gambar 3.5 ERD Implementasi Sistem Pakar Menggunakan Metode

Demptershafer Untuk Mendeteksi Penyakit Gigi

Page 69: untuk memenuhi sebagian persyaratan mencapai derajat

50

3.5.6.5 Analisis Kebutuhan Fungsional

Dalam langkah ini dilakukan penentuan entitas-entitas, atribut yang

mengalir serta prosedur-prosedur yang bisa dilakukan oleh masing-masing entitas.

3.5.6.5.1.Diagram Konteks

Diagram konteks adalah alur data yang berfungsi untuk menggambarkan

keterkaitan aliran-aliran data antara sistem dengan bagian-bagian luar. Adapun

diagram konteks untuk sistem yang akan dibangun.

Gambar 3.6 Diagram Konteks Implementasi Sistem Pakar Menggunakan

Metode Demptershafer Untuk Mendeteksi Penyakit Gigi

Implementasi Sistem

Pakar Gigi

Menggunakan

Metode

Demptershafer

Untuk Mendeteksi

Penyakit Gigi

User Admin

-data user

-konsultasi

-informasi gejala

penyaki gigi

-Info login valid

-Info login gagal

-info gejala yang harus dijawab

-info hasil konsultasi

-Informasi Gejala penyaki gigi

-Data tambah gejala dan

penyebab

-Data ubah gejala, penyebab

gejala

-Data login

-Data berita ditambah,diubah,

dihapus

-Data ganti password

-Info gejala, penyebab telah

ditambahkan

--Info gejala, penyebab telah diubah

-info login valid

-info berita telah ditambahkan,

diubah, dihapus

-Informasi password telah diganti

Page 70: untuk memenuhi sebagian persyaratan mencapai derajat

51

3.5.6.5.2.Data Flow Diagram (DFD)

DFD adalah sebuah teknik yang menggambarkan aliran data dan

transformasi yang digunakan sebagai perjalanan data dari masukan menuju

keluaran.

a) DFD Level 1

DFD Level 1 dibuat jika pada diagram Konteks masih terdapat proses yang

harus dijelaskan lebih rinci. Pada DFD Level, berikut ini :

Gambar 3.7 DFD Level 1 Implementasi Sistem Pakar Menggunakan

Metode Demptershafer Untuk Mendeteksi Penyakit Gigi

Page 71: untuk memenuhi sebagian persyaratan mencapai derajat

52

b) DFD Level 2 Proses 3 Pengolahan Data Master

Proses yang terdapat pada DFD level 2 proses 3 adalah proses pengolahan data

master yang terdiri atas proses 3.1 pengolahan data penyebab, proses 3.2

pengolahan data gejala, proses 3.3 pengobatan dan proses 3.4 data pertanyaan.

dapat dilihat pada gambar 3.4.

Gambar 3.8 DFD Level 1 Proses 3 Pengolahan Data Master

c) DFD Level 2 Proses 5 Pengolahan Konsultasi

Proses yang terdapat pada DFD level 2 proses 5 adalah proses konsultasi yang

terdiri atas proses 5.1 konsultasi, proses 5.2 hasil konsultasi. dapat dilihat pada

gambar 3.5.

Page 72: untuk memenuhi sebagian persyaratan mencapai derajat

53

Gambar 3.9 DFD Level 2 Proses 5 Konsultasi

d) DFD Level 3 Pros 3.1

Proses yang terdapat pada DFD level 3 proses 3.1 adalah proses pengolahan

data penyebab yang terdiri atas proses 3.1.1 tambah data penyebab, proses 3.1.2

ubah data penyebab, dapat dilihat pada gambar 3.6.

Gambar 3.10 DFD Level 3 Pros 3.1 (Pengolahan Data Penyebab)

Page 73: untuk memenuhi sebagian persyaratan mencapai derajat

54

e) DFD Level 3 Pros 3.2

Proses yang terdapat pada DFD level 3 proses 3.2 adalah proses pengolahan

data gejala yang terdiri atas proses 3.2.1 tambah data gejala, proses 3.2.2 ubah

data gejala, dapat dilihat pada gambar 3.7.

Gambar 3.11 DFD Level 3 Pros 3.2 (Pengolahan Data Gejala)

f) DFD Level 3 Pros 3.3

Proses yang terdapat pada DFD level 3 proses 3.3 adalah proses pengolahan

data gejala penyebab yang terdiri atas proses 3.3.1 tambah data gejala penyebab,

proses 3.3.2 ubah data gejala penyebab, proses 3.3.3 hapus data gejala penyebab

dapat dilihat pada gambar 3.8.

Gambar 3.12 DFD Level 3 Pros 3.3 (Pengolahan Data Gejala Penyebab)

Page 74: untuk memenuhi sebagian persyaratan mencapai derajat

55

g) DFD Level 3 Pros 5.1

Proses yang terdapat pada DFD level 3 proses 5.1 adalah proses perhitungan

nilai kepercayaan hasil konsultasi dengan menggunakan metode Dempster-Shafer

yang terdiri atas proses 5.1.1 pengumpulan data gejala, proses 5.5.2 perhitungan

nilai kepercayaan dengan menggunakan metode Dempster- Shafer, dapat dilihat

pada gambar 3.8.

Gambar 3.13 DFD Level 3 Pros 5.1 (Konsultasi)

3.6 Perancangan Sistem

Perancangan aplikasi untuk mengidentifikasi penyebab penyakit pada gigi

menggunakan metode Dempster-Shafer bertujuan untuk menerapkan solusi

pemecahan masalah yang telah diajukan pada analisis sistem.

3.6.1 Perancangan Data

Perancangan data terdiri dari Tabel Relasi dan struktur tabel yang terdapat

pada ERD dari aplikasi untuk mengidentifikasi penyebab penyakit pada gigi.

3.6.1.1 Diagram Relasi

Diagram Relasi menggambarkan suatu hubungan antar tabel yang sudah

ada dalam keadaan normal. Perancangan tabel relasi dalam membangun sebuah

aplikasi untuk mengidentifikasi penyebab penyakit pada gigi adalah sebagai

berikut :

Page 75: untuk memenuhi sebagian persyaratan mencapai derajat

56

Gambar 3.14 Digram relasi Implementasi Sistem Pakar Menggunakan

Metode Demptershafer Untuk Mendeteksi Penyakit Gigi

3.6.1.2 Struktur Tabel

Tabel merupakan tempat penyimpanan informasi dari sebuah aliran data

dalam sebuah sistem. Berikut merupakan struktur dari beberapa tabel sistem yang

akan dibangun.

a). Tabel tbl_diagnosa

Tabel ini berfungsi untuk menghubungkan antara tabel member dan

pertanyaan pada proses diagnosa.

Page 76: untuk memenuhi sebagian persyaratan mencapai derajat

57

Tabel 3.6 Tabel tbl_diagnosa

b). Tabel tbl_gejala

Tabel ini berfungsi untuk menyimpan data gejala pada penyebab penyakit

gigi.

Tabel 3.7 Tabel tbl_gejala

b). Tabel tbl_penyebab penyakit

Tabel ini berfungsi untuk menyimpan data penyebab penyakit.

Tabel 3.8 Tabel tbl_penyebab penyakit

c). Tabel tbl_admin

Tabel ini berfungsi untuk menyimpan data administrator yang nanti akan

mengelola program ini.

Page 77: untuk memenuhi sebagian persyaratan mencapai derajat

58

Tabel 3.9 Tabel tbl_admin

3.7 Pengujian Perangkat Lunak

Pengujian merupakan bagian yang sangat penting dalam siklus

pembangunan perangkat lunak untuk menjamin kualitas dan pemenuhan tujuan

dibangunnya perangkat lunak. Pengujian dilakukan untuk menjamin kualitas dan

juga mengetahui kelemahan dari perangkat lunak. Tujuan dari pengujian ini

adalah untuk menjamin bahwa perangkat lunak yang dibangun memiliki kualitas

yang baik, yaitu sesuai dengan analisis, perancangan dan pengkodean serta

mampu memenuhi kebutuhan pengguna.

3.7.1 Rencana Pengujian

Berikut ini pengujian perangkat lunak pada implementasi sistem pakar

menggunakan metode Dempter Shafer untuk mendekteksi penyakit gigi terdiri

dari :

Tabel 3.10 Tabel Rencana Pengujian

Requirement yang diajukan Butir uji

Login User -Pengisian Username

-Pengisisan Password

Master Data Utama -Pengisian home, penyakit, gejala, basis

aturan, hasil diagnosa, laporan, buku

tamu, pengaturan admin

Penyakit -Berisi table penyakit dan tombol button

Page 78: untuk memenuhi sebagian persyaratan mencapai derajat

59

daftar penyakit, hapus serta ubah

Gejala -Berisi detail data gejala dan tombol

button daftar gejala, hapus serta ubah

Basis Aturan - Berisi detail basis aturan dan tombol

button daftar aturan, hapus serta ubah

Hasil Diagnosa -Berisi data hasil diagnosa dan tombol

button hapus serta ubah

Laporan Hasil Diagnosa Menampilkan laporan hasil diagnosa

Buku Tamu Berisi data tamu yang masuk dan tombol

button hapus serta ubah

Pengaturan Admin Unttuk merubah password

3.7.2 Hasil Pengujian

Berikut adalah hasil pengujian perangkat lunak berdasarkan requirement

pada rencana pengujian :

Tabel 3.11 Tabel Hasil Pengujian

Requirement Diajukan Hasil yang

diharapkan

Hasil

pengujian

Login User 1 Input

username,

password

& level

Masuk sesuai id

yang diakses

(y) diterima

( ) ditolak

Mulai Diagnosa 1

2

Isi Data

Pasien

Klik

Ya/Tidak

gejala

yang

dialami

pasien

Data tersimpan

ke database

Data akan

tersimpan

dibatalkan

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

Basis Aturan

1

2

Klik

tombol

Add daftar

Gejala

Klik

tombol

Data tersimpan

ke database

Data akan

dirubah/ tidak

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

Page 79: untuk memenuhi sebagian persyaratan mencapai derajat

60

3

ubah

Klik

tombol

hapus

Otomatis data

akan terhapus

(y) diterima

( ) ditolak

Master data customer 1

2

3

Klik

tombol

Add daftar

Basis

Aturan

Klik

tombol

ubah

Klik

tombol

hapus

Data tersimpan

ke database

Data akan

dirubah/ tidak

Otomatis data

akan terhapus

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

Hasil Diagnosa

1

2

3

Klik

tombol

Hasil

Diagnosa

Klik

tombol

ubah

Klik

tombol

lihat

diagnosa

Akan tampil

data detail hasil

diagnosa

Data akan

dirubah/ tidak

Tampil data

hasil diagnosa

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

Laporan 1

Klik di

tombol

laporan

Menampilkan

hasil laporan

hasil diagnosa

(y) diterima

( ) ditolak

Buku Tamu 1

2

Klik di

tombol

buku tamu

Klik

tombol

hapus

Menampilkan

data buku tamu

Otomatis data

akan terhapus

(y) diterima

( ) ditolak

(y) diterima

( ) ditolak

Pengaturan Admin 1

Klik

tombol

pengaturan

admin

Data tersimpan

ke database

(y) diterima

( ) ditolak

Page 80: untuk memenuhi sebagian persyaratan mencapai derajat

61

2

Klik

tombol

ubah

Data password

lama akan

diganti dengan

password baru

(y) diterima

( ) ditolak

2.5.3 Kesimpulan dan Hasil Pengujian

Berdasarkan hasil pengujian pada ssetiap inputan proses yang dilakukan,

baik dari sisi administrator maupun dari sisi user, dapat diambil kesimpulan

bahwa sistem yang dibuat telah memenuhi standar pengujian. Sehingga dapat

ditarik kesimpulan bahwa perangkat lunak bebas dari kesalahan sintaks dan secara

fungsional mengeluarkan hasil yang sesuai dengan yang diharapkan.

Page 81: untuk memenuhi sebagian persyaratan mencapai derajat

62

BAB IV

PERANCANGAN DAN IMPLEMENTASI SISTEM

4.1 Perancangan Sistem

Untuk menjawab permasalahan yang timbul baik dari latar belakang serta

rumusan yang telah dijelaskan, berikut gambaran pemecahan masalahnya :

Gambar 4.1 Use Case Sistem Pakar Penyakit Gigi

Dari uses case diatas dapat dijelaskan sebagai berikut :

Tabel 4.1 Use Case Sistem Pakar Gigi

Nama Use Case

Use Case Sistem Pakar gigi

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button mulai diagnose

4. Tampil tampilan menu mulai

diagnosa

User

Menu utama

Pilih konsultasi

Pilih gejala

Hasil diagnosa

Buka aplikasi

Pilih lanjut konsultasi

Use Case Sistem Pakar Penyakit Gigi Santi

Pilih mulai diagnosa

Page 82: untuk memenuhi sebagian persyaratan mencapai derajat

63

5. Isi data pasien dan pilih gejala

dengan di centang

6. Klik button konsultasi

7. Sistem mengkalkulasi inputan

menggunakan metode

8. Muncul hasil diagnose

Untuk menggambarkan interaksi antar objek termasuk pengguna dan

tampilan agar lebih jelas Alur proses konsultasi digambarkan Menggunakan

Sequence diagram sebagai berikut :

(1) Sequence Mulai Diagnosa

Gambar 4.2 Diagram Sequence Mulai Diagnosa

Dari diagram sequence mulai Diagnosa di atas dapat diuraikan sebagai berikut :

Tabel 4.2 Sequence Konsultasi

Nama Use Case

Sequence konsultasi

Aksi actor Aksi Sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen,

lalu masuk ke menu utama

3. Klik button mulai diagnosa

4. Tampil tampilan menu mulai

Menu Konsultasi Gejala Proses data

: User

1 : Buka aplikasi()

2 : Pilih konsultasi()

3 : Pilih gejala()

4 : Proses data()

5 : Tampil hasil diagnosa()

Diagnosa

Use

Case

Siste

m

Pakar

Penya

kit

Gigi

Use

Case

Siste

m

Pakar

Penya

kit

Gigi sa

Menu

Gejala Proses Data

Page 83: untuk memenuhi sebagian persyaratan mencapai derajat

64

dignosa

5. Klik Lanjut konsultasi

6. Tampil Pilihan gejala

7. Pilih gejala yang dialami

8. Klik button proses

9. Metode sistem pakar

menentukan presentase

penyakit yang diderita

10. Tampil hasil diagnosa

(2) Sequence Basis Aturan

Gambar 4.3 Diagram Sequence Basis Aturan

Dari diagram sequence di atas dapat diuraikan sebagai berikut :

Tabel 4.3 Sequence Basis Aturan

Nama Use Case

Sequence Basis Aturan

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

Menu utama Kosultasi Riwayat

: user

1 : Buka aplikasi()

2 : Klik konsultasi()

3 : Klik riwayat()

4 : Tampil Riwayat()

Klik Basis Aturan ()

Tampil Basis Aturan()

Menu

Utama Basis Aturan Riwayat

Page 84: untuk memenuhi sebagian persyaratan mencapai derajat

65

3. Klik button Basis Aturan

4. Tampil tampilan data basis

aturan per enyakit

(3) Sequence Diagram Daftar Gejala

Gambar 4.4 Diagram Sequence Daftar Gejala

Dari diagram sequence di atas dapat diuraikan sebagai berikut :

Tabel 4.4 Sequence Daftar Gejala

Nama Use Case

Sequence daftar gejala

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button daftargejala

4. Tampil tampilan menu daftar

gejala gigi

Menu utama Daftar penyakit Penyakit

: user

1 : Buka aplikasi()

2 : Klik daftar penyakit()

3 : Pilih penyakit()

4 : Tampil penyakit()

Menu

Utama Daftar Gejala Penyakit

Klik daftar gejala()

Tampil daftar gejala()

Page 85: untuk memenuhi sebagian persyaratan mencapai derajat

66

Menu utama Profile

: user

1 : Buka aplikasi()

2 : Klik Profile pembuat()

3 : Tampil proofile pembuat()

(4) Sequence Digram Buku Tamu

Gambar 4.5 Diagram Sequence Buku Tamu

Dari diagram sequence pembuat di atas dapat diuraikan sebagai berikut :

Tabel 4.5 Sequence Buku Tamu

Nama Use Case

Sequence Buku Tamu

Aksi actor Aksi Sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen,

lalu masuk ke menu utama

3. Klik button buku tamu

4. Tampil tampilan menu buku

tamu

Menu Utama Buku Tamu

Klik buku tamu()

Tampil buku tamu()

Page 86: untuk memenuhi sebagian persyaratan mencapai derajat

67

(5) Sequence Diagram Info

Gambar 4.6 Diagram Sequence Laporan

Dari diagram sequence info di atas dapat diuraikan sebagai berikut :

Tabel 4.6 Sequence Laporan

Nama Use Case

Sequence Laporan

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen,

lalu masuk ke menu utama

3. Klik button laporan

4. Tampil tampilan menu cetak

laporan hasil diagnosa

5. Klik button proses dan pilih

tanggal yang ingin diliat

laporannya

6. Tampil tampilan menu laporan

Menu utama Info

: user

1 : Buka aplikasi()

2 : Klik info()

3 : Tampil info()

Klik Laporan()

Laporan

Tampil Laporan()

Menu Utama Laporan

Page 87: untuk memenuhi sebagian persyaratan mencapai derajat

68

(6) Sequence Diagram Pengaturan

Gambar 4.7 Diagram Sequence Pengaturan

Dari diagram sequence di atas dapat diuraikan sebagai berikut :

Tabel 4.7 Sequence Pengaturan

Nama Use Case

Sequence Pengaturan

Aksi actor Aksi Sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen,

lalu masuk ke menu utama

3. Klik button pengaturan

4. Tampil tampilan menu

pengaturan

Menu utama tips

: user1 : Buka aplikasi()

2 : Klik tips()

3 : Tampil tips()

Klik Pengaturan()

Tampil Pengaturan()

Menu Utama Pengaturan

Page 88: untuk memenuhi sebagian persyaratan mencapai derajat

69

(7) Sequence Diagram Keluar

Gambar 4.8 Diagram Sequence Keluar

Dari diagram sequence di atas dapat diuraikan sebagai berikut :

Tabel 4.8 Sequence Keluar

Nama Use Case

Sequence keluar

Aksi actor Aksi Sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button keluar

4. Muncul message box yes/no

5. Klik yes

6. Keluar aplikasi

Untuk mengetahui alur aktivitas dan proses paralel yang mungkin terjadi

pada beberapa eksekusi digambarkan menggunakan diagram activity sebagai

berikut:

Menu utama Keluar

: user1 : Buka aplikasi()

2 : Pilih keluar()

3 : Keluar aplikasi()

Page 89: untuk memenuhi sebagian persyaratan mencapai derajat

70

(1) Activity Diagram Mulai Diagnosa

Gambar 4.9 Diagram activity mulai diagnosa

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.9 Diagram Activity Diagnosa

Nama Use Case

Diagram Activity Mulai Diagnosa

Aksi actor Aksi system

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik butto mulai diagnose

4. Tampil tampilan menu mulai

dignosa

5. Pilih gejala dengan centang

6. Klik button konsultasi

7. Sistem menyimpan nilai ke dalam

database

8. Sistem mengkalkulasi inputan

menggunakan metode

9. Muncul hasil diagnosa

User Sistem

Menu konsultasi

Pilih gejala

Simpan nilai

Kalkulasi

Hasil diagnosa

Buka aplikasi Menu utama

Klik Konsultasi

Klik proses

Page 90: untuk memenuhi sebagian persyaratan mencapai derajat

71

(2) Activity Diagram Basis Aturan

v

Gambar 4.10 Diagram Activity Basis Aturan

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.10 Diagram Activity Basis Aturan

Nama Use Case

Diagram Activity Basis Aturan

Aksi actor Aksi Sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button basis aturan

4. Tampil tampilan menu basis aturan

5. Klik button basis aturan

6. Tampil tampilan detail basis aturan

User Sistem

Buka aplikasi Menu utama

Tampil pembuatKlik pembuatKlik Basis Aturan

Menu Utama

Tampilan Basis

Aturan

Buka Aplikasi

Page 91: untuk memenuhi sebagian persyaratan mencapai derajat

72

(3) Activity Diagram Daftar Penyakit

Gambar 4.11 Diagram Activity Daftar Penyakit

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.11 Diagram Activity Daftar Penyakit

Nama Use Case

Diagram Activity Daftar Penyakit

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button daftar penyakit

4. Tampil tampilan menu daftar

penyakit

5. Klik button penyakitnya

6. Tampil penyakit, gambar dan

keteranganya

User Sistem

Buka aplikasi Menu utama

klik penyakit Tampil penyakit

Klik daftar penyakit Daftar penyakit

Page 92: untuk memenuhi sebagian persyaratan mencapai derajat

73

(4) Activity Diagram Gejala

Gambar 4.12 Diagram Activity Gejala

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.12 Diagram Activity Gejala

Nama Use Case

Diagram Activity Gejala

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button Gejala

4. Tampil tampilan detail data gejala

User Sistem

Buka aplikasi Menu utama

Tampil pembuatKlik pembuatKlik Gejala

Buka Aplikasi

Klik Gejala

Menu Utama

Tampil Gejala

Page 93: untuk memenuhi sebagian persyaratan mencapai derajat

74

(5) Activity Diagram Buku Tamu

Gambar 4.13 Diagram Activity Buku Tamu

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.13 Diagram Activity Buku Tamu

Nama Use Case

Diagram Activity Buku Tamu

Aksi actor Aksi Sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button buku tamu

4. Tampil tampilan menu buku tamu

User Sistem

Buka aplikasi Menu utama

Tampil pembuatKlik pembuatKlik Buku tamu

Tampil Buku tamu

Buka Aplikasi

Klik Buku Tamu

Menu Utama

Tampil Buku Tamu

Page 94: untuk memenuhi sebagian persyaratan mencapai derajat

75

(6) Activity Diagram Hasil Diagnosa

Gambar 4.14 Diagram Activity Hasil Dignosa

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.14 Diagram activity Hasil Diagnosa

Nama Use Case

Diagram activity Hasil Diagnosa

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button hasil diagnose

4. Tampil tampilan menu detail hasil

diagnosa

User Sistem

Buka aplikasi Menu utama

Tampil pembuatKlik pembuat

Buka Aplikasi

Klik Hasil Diagnosa

Menu Utama

Tampil Hasil

Diagnosa

Page 95: untuk memenuhi sebagian persyaratan mencapai derajat

76

(7) Activity Diagram Keluar

Gambar 4.15 Diagram Activity Keluar

Dari diagram activity di atas dapat diuraikan sebagai berikut :

Tabel 4.15 Diagram Activity Keluar

Nama Use Case

Diagram Activity Keluar

Aksi actor Aksi sistem

1. Pengguna membuka aplikasi

2. Akan muncul splash screen, lalu

masuk ke menu utama

3. Klik button keluar

4. Muncul pesan apakah anda yakin

akan keluar? Ya/tidak

5. Pilih ya apabila ingin keluar

6. Keluar aplikasi

7. Pilih tidak jika batal

8. Akan muncul splash screen, lalu

masuk ke menu utama

User Sistem

Menu utama

Klik Keluar

Keluar aplikasi

Ya

Tidak

Buka aplikasi

Page 96: untuk memenuhi sebagian persyaratan mencapai derajat

77

Untuk menentukan kelas - kelas serta relasi antar kelas untuk menentukan

struktur dari sistem yang akan dibuat digambarkan menggunakan class diagram

sebagai berikut :

Gambar 4.16 Class Diagram Sistem Pakar Gigi

4.2 Design Sistem

Merupakan bagian yang menggambarkan bentuk rancangan atau tampilan

dari sistem yang ingin di buat. Pembuatan perancangan ini untuk mempermudah

kita dalam proses pembuatan program nantinya, dan juga sebagai alat komunasi

sistem dengan user. Perancangan ini berisi tampilan serta form - form apa saja

yang di butuhkan serta fitur-fitur yang di sediakan dalam rancangan program agar

lebih efektif dan sesuai dengan harapan.

4.2.1. Rancangan Tampilan Login

Tampilan Login merupakan form tampilan awal pada saat aplikasi pertama

kali di jalankan, form ini hanya muncul dalam durasi beberapa detik dengan

masukan username dan password.

Penyakit

+id+kode+penyakit+status+persen

+simpanstatus()+simpanpersen()+updatenilaistatus()+updatepersen()

Gejala

+id+kode+gejala+status

+deleteid()+deletekode()+deletegejala()+deletestatus()+simpanstatus()+updatenilaistatus()

User

+id+nama+penyakit

+simpannama()+simpanid()+simpanpenyakit()

* 1

*

z

Z

z

z

Page 97: untuk memenuhi sebagian persyaratan mencapai derajat

78

Gambar 4.17 Rancangan Tampilan Login

4.2.2 Rancangan Menu Utama

Menu utama merupakan tampilan menu dari sistem yang di buat, berisikan

beberapa sub - sub form pilihan. Form ini juga dimaksudkan untuk membantu

user dalam memilih menu - menu selanjutnya

Gambar 4.18 Rancangan Tampilan Menu Utama

4.2.3 Rancangan Menu Mulai Diagnosa

Menu mulai dignosa berfungsi untuk melakukan konsultasi, dimana user

harus mengisi data pasien dan memilih gejala - gejala yang di alami dengan cara

mengisi data pasien dan klik pada bagian gejala yang dipilih lalu akan muncul

Home Penyakit Gejala Basis Aturan Hasil Diagnosa Laporan Buku Tamu Pengaturan Admin Logout

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

SISTEM PAKAR DIAGNOSA PENYAKIT GIGI

DEMPSTER SHAFER

Username :

Password :

LOGIN

LOGIN ADMIN

Page 98: untuk memenuhi sebagian persyaratan mencapai derajat

79

contreng biru pada gejala yang dipilih. Setelah user selesai memilih gejala,

kemudian klik button konsultasi maka sistem akan menampilkan hasil diagnosa

berupa gejala yang dipilih, presentasi kemungkinan penyakit .

Gambar 4.19 Rancangan Tampilan Menu Mulai Diagnosa

Setelah gejala di pilih, lalu tekan tombol konsultasi maka muncul hasil

diagnosanya seperti gambar di bawah ini :

Gambar 4.20 Rancangan Tampilan Hasil Diagnosa

Keterangan

Data Pasien :

XXXXXXXXXXXXXXXXXXX

Hasil Diagnosai :

XXXXXXXXXXXXXXXXXXX XXXXX xxxxxx

Kesimpulan hasil konsultasi

KODE GEJALA

Nama

Jenis Kelamin

Usia

Alamat Pasien

Laki-laki

Berikut Daftar Data Gejala :

Konsultasi

Keterangan

DATA PASIEN :

Perempuan

GEJALA PENYAKIT PILIHAN

YA TIDAK E001 Bau Mulut Busuk

Gejala Yang Dihadapi :

Page 99: untuk memenuhi sebagian persyaratan mencapai derajat

80

4.2.4 Rancangan Menu Basis Aturan

Menu Basis Aturan menampilkan penyakit sesuai dengan hasil nilai

densitas gigi. User dapat melihat hasil penyakit sesuai gejala penyakitnya.

Gambar 4.21 Rancangan Tampilan Basis Aturan

4.2.5 Rancangan Menu Daftar Gejala

Gambar 4.22 Rancangan Tampilan Daftar Gejala

Keterangan

Penyakit Gejala

Kode Nama Gejala Nilai Idensitas

Keterangan

DAFTAR GEJALA GIGI :

Penyakit :

No. Gejala

Page 100: untuk memenuhi sebagian persyaratan mencapai derajat

81

4.2.6 Rancangan Menu Buku Tamu

Menu buku tamu menampilkan pesan dari pasien dari hasil menggunakan

aplikasi ini.

Gambar 4.23 Rancangan Tampilan Buku Tamu

4.2.7 Rancangan Menu Penyakit

Menu penyakit menampilkan daftar penyakit pada gigi. Pada menu

penyakit ini administrator dapat menambahkan daftar penyakit dengan klik pada

buttom tambah daftar penyakit serta dapat menghapus daftar penyakit dengan klik

buttom hapus. Dalam menu penyakit juga dapat mengubah daftar penyakit dengan

cara klik button ubah akan muncul form yang akan di isi sesuai dengan hasil dari

nilai believenya.

BUKU TAMU

Nama Tamu :

Email :

Pesan :

f1af63

(masukan 6 kode diatas)

Kirim

Page 101: untuk memenuhi sebagian persyaratan mencapai derajat

82

Gambar 4.24 Rancangan Tampilan Penyakit

4.2.8 Rancangan Menu Hasil Diagnosa

Menu hasil diagnosa berisikan informasi tentang hasil dari data hasil

diagnosa pasien. Adapun fungsi dari form ini untuk melihat data pasien yang

menggunakan sistem ini.

Gambar 4.25 Rancangan Tampilan Hasil Diagnosa

DAFTAR PENYAKIT GIGI :

Tambah Daftar Penyakit Hapus

No. Kode Penyakit Nama Penyakit Pencegahan Pengobatan Nilai Beive Ubah

Jumlah Data :

Halaman :

BERIKUT DETAIL DATA HASIL DIAGNOSA :

Hapus

No. Nama Jenis Kelamin Usia Alamat

Jumlah Data :

Halaman :

Lihat Diagnosa

Page 102: untuk memenuhi sebagian persyaratan mencapai derajat

83

4.2.9 Rancangan Menu Keluar

Menu keluar merupakan menu pilihan untuk keluar dari aplikasi, pada saat

di klik akan muncul pesan “Anda sudah berhasil keluar ?” .

Gambar 4.26 Rancangan Tampilan Keluar

4.3 Implementasi Sistem

Implementasi sistem merupakan tahap pembuatan semua rancangan

yang sudah ada ke dalam sistem sesungguhya. Tampilan yang di buat di bagi

menjadi beberapa modul dan setiap modul berisikan beberapa form.

4.3.1 Tampilan Pada Administrator

4.3.1.1 Tampilan Login

Menu ini sebagai tampilan awal atau pembuka aplikasi, agar bias

membuka menu ini harus mengisi username dan paswordnya kemudian klik

button loginya.

Minggu, 29 Juli 2018 - 2:53:40

Anda sudah berhasil keluar.

Username :

Password :

Login

LOGIN ADMIN

Page 103: untuk memenuhi sebagian persyaratan mencapai derajat

84

Gambar 4.27 Tampilan Login

4.3.1.2 Tampilan Menu Utama

Menu utama sebagai tampilan pilihan untuk melanjutkan ke menu -

menu selanjutnya.

Gambar 4.28 Tampilan Menu Utama

Page 104: untuk memenuhi sebagian persyaratan mencapai derajat

85

4.3.1.3 Tampilan Menu Penyakit

Tampilan ini berisi tentang daftar penyakit pasien yang di derita dan

disini administrator dapat menambahkan daftar penyakit serta menghapusnya.

Gambar 4.29 Tampilan Menu Penyakit

4.3.1.4 Tampilan Menu Gejala

Tampilan menu gejala ini berisi tentang detail data gejala pasien,

disini administrator dapat menambah daftar gejala, hapus dan ubah daftar

gejalanya.

Gambar 4.30 Tampilan Menu Gejala

Page 105: untuk memenuhi sebagian persyaratan mencapai derajat

86

4.3.1.5 Tampilan Menu Basis Aturan

Tampilan menu basis aturan ini berisi tentang detail data basis aturan

pasien, disini administrator dapat menambah daftar gejala, hapus dan ubah

daftar gejalanya.

Gambar 4..31 Tampilan Menu Basis Aturan

4.3.1.6 Tampilan Menu Hasil Diagnosa

Tampilan menu hasil diagnosa ini berisi tentang detail data hasil

diagnosa pasien, disini administrator dapat menghapus dan melihat dignosa

pasien.

Gambar 4.32 Tampilan Menu Hasil Diagnosa

Page 106: untuk memenuhi sebagian persyaratan mencapai derajat

87

4.3.1.7 Tampilan Menu Laporan

Tampilan menu laporan ini berisi tentang laporan hasil diagnosa

pasien dan bisa dilihat sesuai kebutuhan yang ingin dilihat laporan data

pasiennya karena bisa kita search sesuai dengan per minggu, bulan, dan tahun.

Gambar 4.33 Tampilan Menu Laporan

Gambar 4.34 Contoh Tampilan Menu Hasil Laporan

Page 107: untuk memenuhi sebagian persyaratan mencapai derajat

88

4.3.1.8 Tampilan Menu Buku Tamu

Tampilan buku tamu ini berisi tentang data buku tamu pasien dan

administrator dapat menghapus serta melihat data buku tamu pasien.

Gambar 4.35 Tampilan Menu Buku Tamu

4.3.1.9 Tampilan Menu Pengaturan Admin

Tampilan menu pengaturan detail data admin pada saat login dan

administrator dapat mengubah username dan password sesuai kebutuhan.

Gambar 4.36 Tampilan Menu Pengaturan Admin

Page 108: untuk memenuhi sebagian persyaratan mencapai derajat

89

4.3.1.10Tampilan Menu Logout

Tampilan menu logout berfungsi untuk dapat keluar dari aplikasi

tersebut.

Gambar 4.37 Tampilan Menu Logout

4.3.2 Tampilan Pada User

4.3.2.1 Tampilan Menu Utama

Menu utama sebagai tampilan pilihan untuk melanjutkan ke menu -

menu selanjutnya.

Gambar 4.38 Tampilan Menu Utama

Page 109: untuk memenuhi sebagian persyaratan mencapai derajat

90

Untuk konsultasi dengan sistem pakar dapat memilih menu mulai

diagnosa, apabila user ingin melihat hasil dari nilai idensitas per penyakit yang

dikeluhkan dapat dilihat dari data basis aturan , sedangkan menu daftar gejala

berisikan daftar gejala penyakit pasien, menu buku tamu berisikan pesan

terhadap pemakaian aplikasi tersebut, user dapat memilih menu info dan

apabila ingin keluar aplikasi maka pilih keluar.

4.3.2.2 Tampilan Menu Mulai Diagnosa

Menu mulai diagnosa berisikan data pasien dan daftar gejala penyakit

gigi yang sedang diderita pasien, dimana user harus memilih gejala yang di

alami untuk melakukan proses konsultasi lalu di lanjutkan klik tombol

konsultasi.

User dapat memilih beberapa gejala sekaligus dengan klik pada gejala

yang ingin di pilih, gejala yang telah di pilih akan terdapat tanda contreng

hitam.

Gambar 4.39 Tampilan Menu mulai dignosa

Page 110: untuk memenuhi sebagian persyaratan mencapai derajat

91

Setelah di proses maka akan mucul hasil kemungkinan diagnosa

penyakit yang dialami menggunakan presentasi, penyakit dengan presentasi

terbanyak memiliki kemungkinan terbesar penyakit gigi yang di derita.

Gambar 4.40 Tampilan Hasil Diagnosa

4.3.2.3 Tampilan Basis Aturan

Menu Basis aturan berisikan tentang data basis aturan per penyakit

dengan 4.melihat hasil dari nilai densitasnya.

Gambar 4.41 Tampilan Basis Aturan

Page 111: untuk memenuhi sebagian persyaratan mencapai derajat

92

4.3.2.4 Tampilan Daftar Gejala

Menu daftar gejala berisi tentang daftar gejala penyakit gigi yang di

derita pasien.

Gambar 4.42Tampilan Daftar Gejala

4.3.2.5 Tampilan Buku Tamu

Tampilan buku tamu berisi tentang pesan dari pasien yang telah

menggunakan aplikasi program tersebut.

Gambar 4.43 Tampilan Buku Tamu

Page 112: untuk memenuhi sebagian persyaratan mencapai derajat

93

4.4 Pengujian Sistem

Pengujian sistem bertujuan untuk memastikan apakah sistem yang

dirancang sudah sesuai dengan harapan, selain itu untuk memastikan kualitas serta

kehandalan dari sistem ini. Tidak hanya input data tetapi juga berfungsi sesuai

dengan sistem untuk menentukan output yang di harapkan. Untuk pengujian

dilakukan setelah sistem selesai dan siap diuji. Dan hasil dari pengujian tersebut

dituangkan ke dalam sebuah tabel.

4.4.1 Spesifikasi Hardware dan Software

Perangkat keras yang dibutuhkan oleh sistem adalah suatu unit komputer.

Perangkat keras dan perangkat lunak yang diusulkan ini dibuat berdasarkan

kebutuhan sistem saat ini dan antisipasi kabutuhan di masa yang akan datang.

Konfigurasi yang dibutuhkan pada design sistem yang diusulkan, yaitu:

4.3.1.1 Spesifikasi Perangkat Keras

a. Laptop dengan prosesor Intel Dual Core CPU 2.1 GHz 32bit

b. Memory RAM 1 GB

c. Hardisk 160 GB

d. VGA 256 MB

e. Modem/ Wifi/ Hotspot

f. Monitor

g. Mouse & Keyboard

4.3.1.2 Spesifikasi Perangkat Lunak

a. Micrososft Windows xp Sp 3, system operasi yang digunakan pada

website ini

b. Adobe Dreamweaver CS5 digunakan untuk membuat program dan

tampilan website

c. MySQL server

d. Internet Google Chrome sebagai browser internet.

Page 113: untuk memenuhi sebagian persyaratan mencapai derajat

94

4.4.2 Pengujian Pada Menu Konsultasi

Berikut ini hasil dari pengujian sistem yang berupa tabel pengujian pada

menu konsultasi sebagai berikut :

Tabel 4.16 Pengujian Menu Konsultasi

No Skenario

Pengujian Kegiatan

Hasil Yang

Diharapkan

Hasil

Pengujian Kesimpulan

1

Saat klik button

mulai diagnose

akan tampil form

lanjutan

Klik

Tampil form

lanjutan

Tampil

form

lanjutan

Sesuai

2

Saat klik button

lanjut konsultasi

akan tampil form

konsultasi yeng

berisi gejala -

gejala

Klik

Tampil form

konsultasi

Tampil

form

konsultasi

Sesuai

3

Saat klik button

basis aturan akan

mucul data basis

aturan per

penyakit

Klik

Tampil form

basis aturan

per penyakit

Tampil

form basis

aturan per

penyakit

Sesuai

4

Saat pilih daftar

gejala lalu klik

button proses

maka akan

muncul daftar

penyakit gigi

Klik

Tampil form

daftar gejala

Tampil

form daftar

gejala

Sesuai

5

Saat klik buku

tamu akan tampil

form isi buku

tamu

Klik

Tampil form

buku tamu

Tampil

form buku

tamu

Sesuai

4.4.3 Pengujian Pada Menu Daftar Penyakit

Berikut ini hasil dari pengujian sistem yang berupa tabel pengujian pada

menu daftar penyakit sebagai berikut :

Page 114: untuk memenuhi sebagian persyaratan mencapai derajat

95

Tabel 4.17 Pengujian Menu Daftar Penyakit

No Skenario

Pengujian Kegiatan

Hasil Yang

Diharapkan

Hasil

Pengujian Kesimpulan

1

Saat klik

button daftar

penyakit maka

akan tampil

form daftar

penyakit

Klik

Tampil form

daftar penyakit

Tampil

form daftar

penyakit

Sesuai

2

Saat klik

button

penyakit maka

akan tampil

penyakit

Klik

Tampil

penyakit

Tampil

penyakit

Sesuai

4.4.4 Pengujian Pada Menu Buku Tamu

Berikut ini hasil dari pengujian sistem yang berupa tabel pengujian pada

menu buku tamu sebagai berikut :

Tabel 4.18 Pengujian Menu Buku Tamu

No Skenario

Pengujian Kegiatan

Hasil Yang

Diharapkan

Hasil

Pengujian Kesimpulan

1

Saat klik button

buku tamu

maka akan

tampil form

buku tamu

Klik

Tampil form

buku tamu

Tampil form

buku tamu

Sesuai

4.4.5 Pengujian Pada Menu Mulai Dignosa

Berikut ini hasil dari pengujian sistem yang berupa tabel pengujian pada

menu mulai diagnosa sebagai berikut.

Tabel 4.19 Pengujian Menu Menu Mulai Dignosa

No Skenario

Pengujian Kegiatan

Hasil Yang

Diharapkan

Hasil

Pengujian Kesimpulan

1

Saat klik

button mulai

diagnosa

maka akan

Klik

Tampil form

mulai

diagnosa

Tampil form

mulai diagnosa

Sesuai

Page 115: untuk memenuhi sebagian persyaratan mencapai derajat

96

tampil form

diagnosa

2

Saat klik

button

konsultasi

maka menuju

ke hasil

diagnosa

Klik

Tampil form

hasil dignosa

Tampil form

hasil dignosa

Sesuai

4.4.6 Pengujian Menu Pada Gejala

Berikut ini hasil dari pengujian sistem yang berupa tabel pengujian pada

menu gejala sebagai berikut :

Tabel 4.20 Pengujian Menu Gejala

No Skenario

Pengujian Kegiatan

Hasil Yang

Diharapkan

Hasil

Pengujian Kesimpulan

1

Saat klik button

menu gejala

maka akan

tampil form

menu gejala

Klik

Tampil form

menu detail

data gejala

Tampil

form menu

detail data

gejala

Sesuai

4.4.7 Pengujian Pada Menu Keluar

Berikut ini hasil dari pengujian sistem yang berupa tabel pengujian pada

menu keluar sebagai berikut :

Tabel 4.21 Pengujian Menu Keluar

No Skenario

Pengujian Kegiatan

Hasil Yang

Diharapkan

Hasil Pe=-

ngujian Kesimpulan

1

Saat klik

button

Logout Klik

Maka anda

sudah keluar

dari aplikasi

Maka anda

sudah keluar

dari aplikasi

Sesuai

Page 116: untuk memenuhi sebagian persyaratan mencapai derajat

97

BAB V

PENUTUP

5.1 Kesimpulan

Berdasarkan hasil pengembangan dan pembahasan sistem untuk mendiagnosa

penyakit gigi dengan metode Dempster Shafer, maka dapat ditarik kesimpulan

sebagai berikut:

(1) Sistem tidak memerlukan biaya yang mahal karena dapat dijalankan

menggunakan perangkat berbasis Website dengan menggunakan PHP dan

database MySQL.

(2) Hasil dari penelitian ini mampu memberikan informasi seputar gigi sehingga

memberikan pengetahuan gigi kepada penggunanya.

(3) Sistem diimplementasikan ke perangkat website menggunakan metode

Dempster Shafer.

(4) Sistem dapat memberikan hasil diagnosa dengan akurasi tinggi. Sebagai

perhitungan nilai probabilitasnya menggunakan metode Dempster Shafer

yang mengkombinasikan penyakit, gejala dan nilai probabilitas.

(5) Sistem dapat mengetahui jenis penyakit gigi serta penanganan yang tepat

sesuai gejala yang dipilih.

Page 117: untuk memenuhi sebagian persyaratan mencapai derajat

98

5.2 Saran

Berdasarkan penelitian dan pembahasan yang telah dilakukan maka penulis

ingin memberikan saran yang diharapkan dapat berguna untuk pengembang

berikutnya :

(1) Sebaiknya sistem lebih dikembangkan lagi cakupannya, tidak hanya penyakit

gigi tapi juga bisa ditambahkan penyakit mulut pada manusia.

(2) Untuk sistem yang lebih baik mungkin bisa diterapkan sistem database yang

dinamis, sehingga lebih memberikan kemudahan apabila ada perubahan serta

bila ada penambahan - penambahan baik gejala maupun penyakit.

Page 118: untuk memenuhi sebagian persyaratan mencapai derajat

99

DAFTAR PUSTAKA

1. Dahria, Muhammad , Silalahi, Rosindah ,Ramadhan, Mukhlis 2013,

SISTEM PAKAR METODE DEMPSTER SHAFER UNTUK

MENENTUKAN JENIS GANGGUAN PADA ANAK, Medan, Jurnal

STMIK Triguna Dharma.

2. Fadli, Ari 2010, Sistem Pakar Dasar, IlmuKomputer.com.

3. Irawan 2012, Membuat Aplikasi Android Untuk Orang Awam,

Palembang, Maxicom.

4. Khotimah, Bain Khusnul 2010, Sistem Pakar Troubleshooting Komputer

dengan metode Certainty Factor Menggunakan Probabilitas Bayesian,

Madura, Jurnal Universitas Trunojoyo.

5. Kusumawardani, Endah 2011, Buruknya Kesehatan GIGI dan MULUT

Memicu Penyakit Diabetes, Stroke dan Jantung, Yogyakarta, SIKLUS.

6. Masykur, Fauzan 2012, IMPLEMENTASI SISTEM PAKAR

DIAGNOSIS PENYAKIT DIABETES MELLITUS MENGGUNAKAN

METODE FUZZY LOGIC, Semarang, Jurnal UNIVERSITAS

DIPONEGORO SEMARANG.

7. Nurhasanah, Youllia Indrawaty , & Fujiansyah Frenky 2010,

PEMBUATAN SISTEM PAKAR UNTUK MEMPREDIKSI AWAL

PENYAKIT GIGI DAN MULUT BERBASIS WEB DENGAN

METODA BACKWARD CHAINING, Semarang, SEMINAR NASIONAL

ILMU KOMPUTER UNIVERSITAS DIPONEGORO.

Page 119: untuk memenuhi sebagian persyaratan mencapai derajat

100

8. Safaat H, Nazruddin 2012, Pemrograman Aplikasi Mobile Smartphone dan

Tablet PC Berbasis Android, Bandung, Informatika Bandung.

9. Sulistyorini, Prastuti 2009, Pemodelan Visual dengan Menggunakan UML

dan Rational Rose, Yogyakarta, Jurnal Teknologi Informasi DINAMIK

Volume XIV, No.1, Januari 2009 : 23-29.

10. Tim Penerbit ANDI 2009, Pengembangan Sistem Pakar Menggunakan

VISUAL BASIC, Yogyakarta, ANDI.

11. Widodo, Prabowo Pudjo , Herlawati 2011, MENGGUNAKAN UML

Secara Luas Digunakan Untuk Memodelkan Analisis & Desain Sistem

Berorientasi Objek, Bandung, Infromatika Bandung.

Page 120: untuk memenuhi sebagian persyaratan mencapai derajat

101

4.4. Potongan Koding Program

Dari desain yang telah di buat di atas di tambahkan koding program agar

aplikasi dapat berjalan seperti yang di inginkan. Koding program yang di gunakan

adalah sebagai berikut :

4.4.1 Koding Home

<div class='sputih'><div class='judul'>

<h3><p>Selamat Datang <?php echo $_SESSION['nama_lengkap'] ?> di

Halaman Administrator</p></h3>

<p></p>

<br />

Disini anda bisa mengolah data baik dari Penyakit maupun Data Gejala , anda bisa

merubah menghapus dan menambahkan data

<p> Silahkan Lihat menu diatas </p>

</div></div>

4.4.2 Koding Main Menu

<?php

include "../../config/class_paging.php";

include "../../config/inc.library.php";

$main = $_GET['main'];

if ($main == 'home'){

include "home.php";

}

elseif($main == 'setuser'){

include "main/main_admin/setadmin.php";

}

elseif($main == 'penyakit'){

include "main/main_penyakit/penyakit.php";

Page 121: untuk memenuhi sebagian persyaratan mencapai derajat

102

}

elseif($main == 'addpenyakit'){

include "main/main_penyakit/add_penyakit.php";

}

elseif($main == 'simpanpenyakit'){

include "main/main_penyakit/proses_addpenyakit.php";

}

elseif($main == 'updatepenyakit'){

include "main/main_penyakit/proses_updatepenyakit.php";

}

elseif($main == 'gejala'){

include "main/main_gejala/gejala.php";

}

elseif($main == 'simpangejala'){

include "main/main_gejala/proses_addgejala.php";

}

elseif($main == 'updategejala'){

include "main/main_gejala/proses_updategejala.php";

}

elseif($main == 'aturan'){

include "main/main_aturan/aturan.php";

}

elseif($main == 'add_aturan'){

include "main/main_aturan/add_aturan.php";

}

Page 122: untuk memenuhi sebagian persyaratan mencapai derajat

103

elseif($main == 'edit_aturan'){

include "main/main_aturan/edit_aturan.php";

}

elseif($main == 'simpanaturan'){

include "main/main_aturan/proses_addaturan.php";

}

elseif($main == 'updateaturan'){

include "main/main_aturan/proses_updateaturan.php";

}

elseif($main == 'bukutamu'){

include "main/main_bukutamu/bukutamu.php";

}

elseif($main == 'hasildiagnosa'){

include "main/main_hasildiagnosa/hasildiagnosa.php";

}

elseif($main == 'laporandiagnosa'){

include "main/main_laporan/laporan.php";

}

else {

echo "Halaman tidak Ada";

}

?>

4.4.3 Logout

<?php

session_start();

session_destroy();

header('location:../../index.php?logout=1');

?>

Page 123: untuk memenuhi sebagian persyaratan mencapai derajat

104

4.4.4 Main_admin

a. Proses_updateadmin

<?php

include "../../../../config/koneksi.php";

if ($_GET['main'] == 'private'){

$id= $_POST['id'];

$r = mysql_fetch_array(mysql_query("SELECT * FROM admin

WHERE id_session = '$id' "));

$pass_lama=md5($_POST['passold']);

$pass_baru=md5($_POST['passnew']);

if (empty($_POST["passnew"]) OR empty($_POST["passold"]) OR

empty($_POST["passnew2"])){

echo "<script>window.alert('Wajib isikan password lama

sebelumnya dan Password Baru sebanyak dua kali ');

window.location=('../../index.php?main=setuser')</script>";

} else {

// Apabila password lama cocok dengan password admin di database

if ($r['password'] == $pass_lama){

// Pastikan bahwa password baru yang dimasukkan sebanyak dua kali

sudah cocok

if ($_POST["passnew"]==$_POST["passnew2"]){

mysql_query("UPDATE admin SET password = '$pass_baru'

WHERE id_session = '$id'");

session_start();

session_destroy();

header('location:../../../index.php?reset=3');

}

else{

Page 124: untuk memenuhi sebagian persyaratan mencapai derajat

105

echo "<script>window.alert('Password baru yang Anda

masukkan sebanyak dua kali belum cocok.');

window.location=('../../index.php?main=setuser')</script>";

}

} else {

echo "<script>window.alert('Anda salah memasukkan Password

Lama Anda ');

window.location=('../../index.php?main=setuser')</script>";

}

}

} else {

$id= $_POST['id'];

$nm = $_POST['nama'];

$telp = $_POST['telp'];

$email = $_POST['email'];

mysql_query("UPDATE admin SET nama_lengkap = '$nm', no_telp =

'$telp', email = '$email' WHERE id_session = '$id'");

echo "<script>window.alert('Anda telah berhasil update data');

window.location=('../../index.php?main=setuser')</script>";

}

?>

b. Setadmin

<script src="../ajax/jquery.validate.min.js"

type="text/javascript"></script>

<script type="text/javascript">

$(document).ready(function(){

$("#frm").validate({

debug: false,

rules: {

Page 125: untuk memenuhi sebagian persyaratan mencapai derajat

106

nama: "required",

user: "required",

telp : "required"

},

messages: {

nama: "<font

style='color:#FF0000;'>* Masukan nama lengkap Anda</font>",

user: "<font

style='color:#FF0000;'>* Username Tidal boleh kosong</font>",

telp: "<font

style='color:#FF0000;'>* Kosong</font>"

},

submitHandler: function(form) {

// do other stuff for a valid

form

$.post('logistik_data/log_users/prosses_update.php',

$("#frm").serialize(), function(data) {

$('#hasil').html(data);

$('#divResult').text('Data berhasil

diupdate').css({'color':'#000000','background-

color':'#FFFF00'}).fadeIn();

});

}

});

});

</script>

Page 126: untuk memenuhi sebagian persyaratan mencapai derajat

107

<?php

require "../../config/koneksi.php";

$qryuser = mysql_query ("select * from admin ") or die('MySql Error' .

mysql_error());

$us = mysql_fetch_array($qryuser);

?>

<div class=judul><h2>Berikut detail data

admin:</h2></div><br/><br/><br/><br/>

<form method="POST"

action="main/main_admin/proses_updateadmin.php?main=nama"

name="frm">

<table>

<tr><td width="150px">Nama Lengkap</td><td> : <input

value='<?php echo $us['nama_lengkap']; ?>' type="text"

name="nama"></td></tr>

<tr><td>No. Telp</td><td> : <input value='<?php echo

$us['no_telp']; ?>' type="text" name="telp"></td></tr>

<tr><td>Email</td><td> : <input value='<?php echo

$us['email']; ?>' type="text" name="email"></td></tr>

<tr><td></td><td></td></tr>

<tr><td></td>

<td>&nbsp;&nbsp;&nbsp; &nbsp;

<input type=hidden name="id" value='<?php echo

$us['id_session'] ?>' >

<input type="submit" name="submit"

value="Ubah" >

</td></tr>

</table>

</form><br/><br/>

Page 127: untuk memenuhi sebagian persyaratan mencapai derajat

108

<form method="POST"

action="main/main_admin/proses_updateadmin.php?main=private"

name="frm">

<table>

<tr><td width="150px">Username</td><td> : <input

type="text" value=<?php echo $us['username']; ?>

disabled></td></tr>

<tr><td>Password Lama</td><td> : <input

type="password" name="passold"></td></tr>

<tr><td>Password Baru</td><td> : <input

type="password" name="passnew" ></td></tr>

<tr><td>Ulangi Password Baru</td><td> : <input

type=password name="passnew2" ></td></tr>

<tr><td></td><td></td></tr>

<tr><td></td>

<td>&nbsp;&nbsp;&nbsp; &nbsp;

<input type=hidden name="id" value='<?php echo

$us['id_session'] ?>' >

<input type="submit" name="submit"

value="Ubah" >

</td></tr>

</table>

</form>

4.4.5 Main_aturan

a. Add_aturan

<?php

require "../../../../config/koneksi.php";

$dataPenyakit = isset($_POST['cmbPenyakit']) ?

$_POST['cmbPenyakit'] : '';

Page 128: untuk memenuhi sebagian persyaratan mencapai derajat

109

$dataGejala = isset($_POST['cmbGejala']) ?

$_POST['cmbGejala'] : '';

$dataProbabilitas = isset($_POST['txtProbabilitas']) ?

$_POST['txtProbabilitas'] : '';

?>

<div class="add">

<fieldset>

<legend>Tambah Daftar Basis Aturan</legend>

<div ></div>

<form action="?main=simpanaturan" method="post"

name="form1" target="_self">

<table class="table-list" width="100%">

<tr>

<th colspan="3">TAMBAH DATA ATURAN </th>

</tr>

<tr>

<td width="15%"><b>Nama Penyakit </b></td>

<td width="1%"><b>:</b></td>

<td width="84%"><select name="cmbPenyakit">

<option value="Kosong"> .... </option>

<?php

$daftarSql = "SELECT * FROM penyakit ORDER BY

kd_penyakit";

$daftarQry = mysql_query($daftarSql, $koneksidb) or die ("Gagal

Query".mysql_error());

while ($daftarData = mysql_fetch_array($daftarQry)) {

if ($daftarData['kd_penyakit'] == $dataPenyakit) {

$cek = " selected";

} else { $cek=""; }

Page 129: untuk memenuhi sebagian persyaratan mencapai derajat

110

echo "<option value='$daftarData[kd_penyakit]'

$cek>$daftarData[kd_penyakit] | $daftarData[nm_penyakit]</option>";

}

?>

</select></td>

</tr>

<tr>

<td><b>Nama Gejala </b></td>

<td><b>:</b></td>

<td><select name="cmbGejala">

<option value="Kosong"> .... </option>

<?php

$daftarSql = "SELECT * FROM gejala ORDER BY kd_gejala";

$daftarQry = mysql_query($daftarSql, $koneksidb) or die ("Gagal

Query".mysql_error());

while ($daftarData = mysql_fetch_array($daftarQry)) {

if ($daftarData['kd_gejala'] == $dataGejala) {

$cek = " selected";

} else { $cek=""; }

echo "<option value='$daftarData[kd_gejala]'

$cek>$daftarData[kd_gejala] | $daftarData[nm_gejala]</option>";

}

?>

</select></td>

</tr>

<tr>

<td><b>Nilai Densitas </b></td>

<td><b>:</b></td>

<td><input name="txtProbabilitas" type="text" value="<?php

echo $dataProbabilitas; ?>" size="10" maxlength="10" /></td>

</tr>

Page 130: untuk memenuhi sebagian persyaratan mencapai derajat

111

<tr><td>&nbsp;</td>

<td>&nbsp;</td>

<td><input type="submit" name="btnSimpan" value=" SIMPAN

"></td>

</tr>

</table>

</form>

</fieldset>

</div>

b. Aturan

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".thickbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".colorbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<?php

Page 131: untuk memenuhi sebagian persyaratan mencapai derajat

112

if (isset($_POST['Del'])) {

if ($_POST['cex'] == NULL) {

echo "<script>window.alert('Data yang akan dihapus belum di

pilih')

javascript:history.go(-1);</script>";

} else {

$a = join(",", $_POST['cex']);

$tampil=mysql_query("SELECT * FROM aturan

Where id_aturan IN(" . $a . ")");

while($r=mysql_fetch_array($tampil)){

}

mysql_query("DELETE FROM aturan WHERE

id_aturan='$a'");

print "<script>alert('Data berhasil di dihapus');

javascript:history.go(-

1);</script>";

}

}else{

echo "

<div class=judul><h2>Berikut Detail Basis Aturan:</h2></div>

<br/>

<form action='' method='post'>

<div style='float:right; padding:10px; width:250px; margin-top:5px;'>

<a class='thickbox' href='main/main_aturan/add_aturan.php'>Add

Daftar Aturan</a>

<input type='submit' name='Del' value='Hapus' onclick='return

confirmDelete();'>

</div><br/>

<table id=o width=100%><tbody>

Page 132: untuk memenuhi sebagian persyaratan mencapai derajat

113

<tr>

<th width='1%' class=th>No</th>

<th width='1%' class=th>Kode Penyakit</th>

<th width='1%' class=th>Kode Gejala</th>

<th width='10%' class=th>Nilai Densitas</th>

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'>Ubah</span></div></th>

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'><input type='checkbox'

name='checkbox[]' class='checkall'></span></div></th>

</tr>";

$p = new Paging;

$batas = 15;

$posisi = $p->cariPosisi($batas);

$tampil=mysql_query("SELECT aturan.*, penyakit.nm_penyakit,

gejala.nm_gejala FROM aturan

LEFT JOIN penyakit ON aturan.kd_penyakit =

penyakit.kd_penyakit

LEFT JOIN gejala ON aturan.kd_gejala =

gejala.kd_gejala

ORDER BY aturan.kd_penyakit, aturan.kd_gejala

desc LIMIT $posisi,$batas");

$no=1;

$i = $posisi;

while ($r=mysql_fetch_array($tampil)){

if (($no % 2) > 0)

$bg = '#FFFFFF'; else

$bg = '#cccccc';

echo "<tr bgcolor=" . $bg . "><td class=td align=center>$no</td>

<td class=td>$r[kd_penyakit]</td>

<td class=td>$r[kd_gejala]</td>

Page 133: untuk memenuhi sebagian persyaratan mencapai derajat

114

<td class=td>$r[nilai_probabilitas]</td>

<td><div align='center' style='background-

color:none;'><a class='colorbox'

href=main/main_aturan/edit_aturan.php?Kode=" . $r['id_aturan'] . "

><img src='../images/edit.png' border='0' width='16' height='16'

/></a></div></td>

<td><div align='center'><input type='checkbox' name='cex[]'

value='" . $r['id_aturan'] . "'></div></td>

</tr></tr>";

$no++;

}

echo "</tbody></table></form>";

$sql_pagging = mysql_query("SELECT COUNT(*) AS jml FROM

aturan");

$pagging = mysql_fetch_array($sql_pagging);

$jml = $pagging['jml'];

echo"

</br>

<div class='results'> <span>Jumlah Data : $jml</span><br/><br/>

";

$jmldata = mysql_num_rows(mysql_query("SELECT * from

aturan"));

$jmlhalaman = $p->jumlahHalaman($jmldata, $batas);

$linkHalaman = $p->navHalaman($_GET['halaman'], $jmlhalaman);

echo" Halaman : $linkHalaman </div>";

}

?>

Page 134: untuk memenuhi sebagian persyaratan mencapai derajat

115

c. Edit_aturan

<?php

require "../../../../config/koneksi.php";

$Kode = isset($_GET['Kode']) ? $_GET['Kode'] :

$_POST['txtKode'];

$mySql = "SELECT * FROM aturan WHERE id_aturan='$Kode'";

$myQry = mysql_query($mySql, $koneksidb) or die ("Query ambil

data salah : ".mysql_error());

$myData = mysql_fetch_array($myQry);

// Menyimpan data ke variabel temporary (sementara)

$dataKode = $myData['id_aturan'];

$dataPenyakit = isset($_POST['cmbPenyakit']) ?

$_POST['cmbPenyakit'] : $myData['kd_penyakit'];

$dataGejala = isset($_POST['cmbGejala']) ?

$_POST['cmbGejala'] : $myData['kd_gejala'];

$dataProbabilitas = isset($_POST['txtProbabilitas']) ?

$_POST['txtProbabilitas'] : $myData['nilai_probabilitas'];

?>

<div class="add">

<fieldset>

<legend>Edit Basis Aturan <?php echo $q['id_aturan'] ?></legend>

<div ></div>

<form action="?main=updateaturan" method="post"

name="form1">

<table class="table-list" width="100%">

<tr>

<th colspan="3">UBAH DATA ATURAN </th>

</tr>

Page 135: untuk memenuhi sebagian persyaratan mencapai derajat

116

<tr>

<td width="15%"><b>Nama Penyakit </b></td>

<td width="1%"><b>:</b></td>

<td width="84%"><select name="cmbPenyakit">

<option value="Kosong"> .... </option>

<?php

$daftarSql = "SELECT * FROM penyakit ORDER BY

kd_penyakit";

$daftarQry = mysql_query($daftarSql, $koneksidb) or die ("Gagal

Query".mysql_error());

while ($daftarData = mysql_fetch_array($daftarQry)) {

if ($daftarData['kd_penyakit'] == $dataPenyakit) {

$cek = " selected";

} else { $cek=""; }

echo "<option value='$daftarData[kd_penyakit]'

$cek>$daftarData[kd_penyakit] | $daftarData[nm_penyakit]</option>";

}

?>

</select>

<input name="txtKode" type="hidden" value="<?php echo

$dataKode; ?>" /></td></tr>

<tr>

<td><b>Nama Gejala </b></td>

<td><b>:</b></td>

<td><select name="cmbGejala">

<option value="Kosong"> .... </option>

<?php

$daftarSql = "SELECT * FROM gejala ORDER BY kd_gejala";

$daftarQry = mysql_query($daftarSql, $koneksidb) or die ("Gagal

Query".mysql_error());

while ($daftarData = mysql_fetch_array($daftarQry)) {

Page 136: untuk memenuhi sebagian persyaratan mencapai derajat

117

if ($daftarData['kd_gejala'] == $dataGejala) {

$cek = " selected";

} else { $cek=""; }

echo "<option value='$daftarData[kd_gejala]'

$cek>$daftarData[kd_gejala] | $daftarData[nm_gejala]</option>";

}

?>

</select>

<input name="txtLama" type="hidden" value="<?php echo

$myData['kd_gejala']; ?>" /></td>

</tr>

<tr>

<td><b>Nilai Densistas (%) </b></td>

<td><b>:</b></td>

<td><input name="txtProbabilitas" type="text" value="<?php

echo $dataProbabilitas; ?>" size="10" maxlength="10" /></td>

</tr>

<tr><td>&nbsp;</td>

<td>&nbsp;</td>

<td><input type="submit" name="btnSimpan" value=" SIMPAN

"></td>

</tr>

</table>

</form>

</fieldset>

</div>

d. Proses_addaturan

<?php

session_start();

Page 137: untuk memenuhi sebagian persyaratan mencapai derajat

118

require "../../config/koneksi.php";

# Tombol Simpan diklik

if(isset($_POST['btnSimpan'])){

# Baca Variabel Form

$cmbPenyakit = $_POST['cmbPenyakit'];

$cmbGejala = $_POST['cmbGejala'];

$txtProbabilitas= $_POST['txtProbabilitas'];

$txtProbabilitas= str_replace(",",".",$txtProbabilitas); // mengubah

tanda koma(,) menjadi titik (.), misalnya: 0,5 menjadi 0.5 (desimal)

# Validasi form, jika kosong sampaikan pesan error

$pesanError = array();

if (trim($cmbPenyakit)=="Kosong") {

$pesanError[] = "Data <b>Nama Penyakit</b> belum ada

yang dipilih !";

}

if (trim($cmbGejala)=="Kosong") {

$pesanError[] = "Data <b>Nama Gejala</b> belum ada

yang dipilih !";

}

if (trim($txtProbabilitas)=="") {

$pesanError[] = "Data <b>Nilai Densitas (%)</b> tidak

boleh kosong !";

}

# Validasi Nama aturan, jika sudah ada akan ditolak

$cekSql="SELECT * FROM aturan WHERE

kd_penyakit='$cmbPenyakit' AND kd_gejala='$cmbGejala'";

$cekQry=mysql_query($cekSql, $koneksidb) or die ("Eror

Query".mysql_error());

if(mysql_num_rows($cekQry)>=1){

Page 138: untuk memenuhi sebagian persyaratan mencapai derajat

119

$pesanError[] = "Maaf, aturan <b> $cmbPenyakit</b> dan

<b>$cmbGejala</b> sudah ada, ganti dengan yang lain";

}

# JIKA ADA PESAN ERROR DARI VALIDASI

if (count($pesanError)>=1 ){

echo "<div class='mssgBox'>";

echo "<img src='../images/attention.png'> <br><hr>";

$noPesan=0;

foreach ($pesanError as $indeks=>$pesan_tampil) {

$noPesan++;

echo "&nbsp;&nbsp; $noPesan.

$pesan_tampil<br>";

}

echo "</div> <br>";

}

else {

# SIMPAN DATA KE DATABASE.

// Jika tidak menemukan error, simpan data ke database

$mySql = "INSERT INTO aturan (kd_penyakit,

kd_gejala, nilai_probabilitas)

VALUES ('$cmbPenyakit',

'$cmbGejala', '$txtProbabilitas')";

$myQry = mysql_query($mySql, $koneksidb) or die

("Gagal query".mysql_error());

if($myQry){

echo "<meta http-equiv='refresh' content='0;

url=?main=aturan'>";

}

exit;

}

Page 139: untuk memenuhi sebagian persyaratan mencapai derajat

120

} // Penutup Tombol Simpan

?>

e. Proses_updateaturan

<?php

require "../../config/koneksi.php";

# Tombol Simpan diklik

if(isset($_POST['btnSimpan'])){

# Baca Variabel Form

$cmbPenyakit = $_POST['cmbPenyakit'];

$cmbGejala = $_POST['cmbGejala'];

$txtProbabilitas= $_POST['txtProbabilitas'];

$txtProbabilitas= str_replace(",",".",$txtProbabilitas); // mengubah

tanda koma(,) menjadi titik (.), misalnya: 0,5 menjadi 0.5 (desimal)

# Validasi form, jika kosong sampaikan pesan error

$pesanError = array();

if (trim($cmbPenyakit)=="Kosong") {

$pesanError[] = "Data <b>Nama Penyakit</b> belum ada

yang dipilih !";

}

if (trim($cmbGejala)=="Kosong") {

$pesanError[] = "Data <b>Nama Gejala</b> belum ada

yang dipilih !";

}

if (trim($txtProbabilitas)=="") {

$pesanError[] = "Data <b>Nilai Densitas (%)</b> tidak

boleh kosong !";

}

# Validasi Nama aturan, jika sudah ada akan ditolak

$txtLama = $_POST['txtLama'];

Page 140: untuk memenuhi sebagian persyaratan mencapai derajat

121

$cekSql="SELECT * FROM aturan WHERE

kd_penyakit='$cmbPenyakit' AND kd_gejala='$cmbGejala' AND

NOT(kd_gejala='$txtLama')";

$cekQry=mysql_query($cekSql, $koneksidb) or die ("Eror

Query".mysql_error());

if(mysql_num_rows($cekQry)>=1){

$pesanError[] = "Maaf, aturan <b> $cmbPenyakit</b> dan

<b>$cmbGejala</b> sudah ada, ganti dengan yang lain";

}

# JIKA ADA PESAN ERROR DARI VALIDASI

if (count($pesanError)>=1 ){

echo "<div class='mssgBox'>";

echo "<img src='../images/attention.png'> <br><hr>";

$noPesan=0;

foreach ($pesanError as $indeks=>$pesan_tampil) {

$noPesan++;

echo "&nbsp;&nbsp; $noPesan.

$pesan_tampil<br>";

}

echo "</div> <br>";

}

else {

# SIMPAN PERUBAHAN DATA, Jika jumlah error

pesanError tidak ada, simpan datanya

$Kode = $_POST['txtKode'];

$mySql = "UPDATE aturan SET

kd_penyakit='$cmbPenyakit', kd_gejala='$cmbGejala',

nilai_probabilitas='$txtProbabilitas'

WHERE id_aturan ='$Kode'";

Page 141: untuk memenuhi sebagian persyaratan mencapai derajat

122

$myQry = mysql_query($mySql, $koneksidb) or die

("Gagal query".mysql_error());

if($myQry){

echo "<meta http-equiv='refresh' content='0;

url=?main=aturan'>";

}

exit;

}

} // Penutup Tombol Simpan

?>

4.4.6 Main_bukutamu

a. Bukutamu

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".thickbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".colorbox").colorbox({width:"50%",

height:"75%"});

});

</script>

Page 142: untuk memenuhi sebagian persyaratan mencapai derajat

123

<?php

if (isset($_POST['Del'])) {

if ($_POST['cex'] == NULL) {

echo "<script>window.alert('Data yang akan dihapus belum di

pilih')

javascript:history.go(-1);</script>";

} else {

$a = join(",", $_POST['cex']);

mysql_query("DELETE FROM bukutamu WHERE

id_bukutamu IN(" . $a . ")");

print "<script>alert('Data berhasil di dihapus');

javascript:history.go(-

1);</script>";

}

}else{

echo "

<body>

<div class='judul'><h1>DATA BUKU TAMU</h1></div><br/>

<br/>

<form action='' method='post'>

<div style='float:right; padding:10px; width:70px; margin-top:5px;'>

<input type='submit' name='Del' value='Hapus' onclick='return

confirmDelete();'>

</div><br/>

<table width='100%' border='0' align='center'

style='margin-bottom:50px;'>

<tr>

Page 143: untuk memenuhi sebagian persyaratan mencapai derajat

124

<th width='1%' bgcolor='#8DAD9C'><div align='center'

class='style1'>NO</div></th>

<th width='20%' bgcolor='#8DAD9C'><div align='center'

class='style1'>Nama</div></th>

<th width='20%' bgcolor='#8DAD9C'><div align='center'

class='style1'>Email</div></th>

<th width='10%' bgcolor='#8DAD9C'><div align='center'

class='style1'>Tanggal</div></th>

<th width='2%' bgcolor='#8DAD9C'><div align='center'

class='style1'>Status</div></th>

<th width='1%' bgcolor='#8DAD9C'><div align='center'><span

class='style1'>Lihat</span></div></th>

<th width='1%' bgcolor='#8DAD9C'><div align='center'><span

class='style1'><input type='checkbox' name='checkbox[]'

class='checkall'></span></div></th>

</tr>";

$p = new Paging;

$batas = 10;

$posisi = $p->cariPosisi($batas);

$sql = mysql_query("SELECT * FROM bukutamu order by

id_bukutamu desc LIMIT $posisi,$batas");

$i = 0;

$i = $posisi;

while ($r = mysql_fetch_array($sql)) {

if (($i % 2) > 0)

$bg = '#FFFFFF'; else

$bg = '#cccccc';

$pilihan_status = array('Y','N');

$pilih_status = '';

Page 144: untuk memenuhi sebagian persyaratan mencapai derajat

125

foreach ($pilihan_status as $status) {

$pilih_status .= "<option value='$status'";

if ($status == $r['publish']) {

$pilih_status .= " selected";

}

$pilih_status .= ">$status</option>\r\n";

}

echo"

<tr bgcolor=" . $bg . ">

<td><div align='center'>" . ++$i . "</div></td>

<td><div align='left'>" . $r['nama'] . "</div></td>

<td><div align='left'>" . $r['email'] . "</div></td>

<td><div align='center'>". $r['tanggal'] . "</div></td>

<td><div align='center'>". $r['publish'] . "</div></td>

<td><div align='center' style='background-color:none;'><a

class='colorbox' href=main/main_bukutamu/view_bukutamu.php?id=" .

$r['id_bukutamu'] . " ><img src='../images/dt.png' border='0' width='16'

height='16' /></a></div></td>

<td><div align='center'><input type='checkbox' name='cex[]'

value='" . $r['id_bukutamu'] . "'></div></td>

</tr>";

} echo"</table></form>";

$sql_pagging = mysql_query("SELECT COUNT(*) AS jml FROM

bukutamu");

$pagging = mysql_fetch_array($sql_pagging);

$jml = $pagging['jml'];

echo"

Page 145: untuk memenuhi sebagian persyaratan mencapai derajat

126

<div class='results'> <span>Jumlah Data : $jml</span><br/><br/>

";

$jmldata = mysql_num_rows(mysql_query("SELECT * from

bukutamu"));

$jmlhalaman = $p->jumlahHalaman($jmldata, $batas);

$linkHalaman = $p->navHalaman($_GET['halaman'], $jmlhalaman);

echo" Halaman : $linkHalaman

</div>";

}

?>

b. Proses_bukutamu

<?php

require "../../../../config/koneksi.php";

$id = $_REQUEST['id'];

$val = $_REQUEST['val'];

$query = mysql_query("UPDATE bukutamu SET publish = '$val'

Where id_bukutamu = '$id'");

if ($val == '') $val = "_show";

if ($query){

echo "Fields" . "$id" . "|" . stripslashes($val);

}

echo "<meta http-equiv='refresh' content='0;

url=../../index.php?main=bukutamu'>";

?>

c. View_bukutamu

<?php

session_start();

require "../../../../config/koneksi.php";

Page 146: untuk memenuhi sebagian persyaratan mencapai derajat

127

$id = $_GET['id'];

$sql = mysql_query("SELECT * FROM bukutamu Where id_bukutamu

= '$id'");

$r = mysql_fetch_array($sql);

?>

<div class="add">

<fieldset>

<legend>Edit Buku Tamu</legend>

<div ></div>

<form method="POST"

action="main/main_bukutamu/proses_bukutamu.php">

<input type=hidden name="id" value='<?php echo

$r['id_bukutamu'] ?>'>

<table class="in">

<tr><td>Nama</td><td> : <?php echo $r['nama'] ?></td></tr>

<tr><td>Email</td><td> : <?php echo $r['email'] ?></td></tr>

<tr><td>Pesan</td><td> : <?php echo $r['pesan']

?></td></tr>

<tr><td>Tanggal</td><td> : <?php echo $r['tanggal']

?></td></tr>

<?php if ($r['publish']=='N'){

echo "<tr><td>Tampilkan</td> <td> : <input type=radio name='val'

value='N' checked> N

<input type=radio name='val' value='Y'>

Y</td></tr>";

}

else{

echo "<tr><td>Tampilkan</td> <td> : <input type=radio name='val'

value='N'> N

Page 147: untuk memenuhi sebagian persyaratan mencapai derajat

128

<input type=radio name='val' value='Y'

checked> Y</td></tr>";

} ?>

<tr><td></td>

<td>&nbsp;&nbsp;&nbsp; &nbsp;

<input type="submit" name="submit"

value="Simpan">

</td></tr>

</table>

</form>

</fieldset>

</div>

4.4.7 Main_gejala

a. Add_gejala

<?php

session_start();

require "../../../../config/koneksi.php";

require "../../../../config/inc.library.php";

$dataKode = buatKode("gejala", "E");

$dataNama = isset($_POST['txtNama']) ? $_POST['txtNama'] : '';

?>

<script type="text/javascript">

function harusangka(jumlah){

var karakter = (jumlah.which) ? jumlah.which : event.keyCode

if (karakter > 31 && (karakter < 46 || karakter > 57))

return (false);

return (true);

}

Page 148: untuk memenuhi sebagian persyaratan mencapai derajat

129

</script>

<link href="../../../../style/style.css" rel="stylesheet" type="text/css" />

<div class="add">

<fieldset>

<legend>Tambah Daftar Gejala</legend>

<div ></div>

<form action="?main=simpangejala" method="post"

name="form1" target="_self">

<table class="table-list" width="100%">

<tr>

<th colspan="3">TAMBAH GEJALA </th>

</tr>

<tr>

<td width="15%"><b>Kode</b></td>

<td width="1%"><b>:</b></td>

<td width="84%"><input name="textfield" value="<?php echo

$dataKode; ?>" size="10" maxlength="4"

readonly="readonly"/></td></tr>

<tr>

<td><b>Nama Gejala </b></td>

<td><b>:</b></td>

<td><input name="txtNama" value="<?php echo $dataNama; ?>"

size="80" maxlength="100" /></td>

</tr>

<tr><td>&nbsp;</td>

<td>&nbsp;</td>

<td><input type="submit" name="btnSimpan" value=" SIMPAN

"></td>

</tr>

</table>

Page 149: untuk memenuhi sebagian persyaratan mencapai derajat

130

</form>

</fieldset>

</div>

b. Edit_gejala

<?php

session_start();

require "../../../../config/koneksi.php";

require "../../../../config/inc.library.php";

# TAMPILKAN DATA LOGIN UNTUK DIEDIT

$Kode = isset($_GET['Kode']) ? $_GET['Kode'] :

$_POST['txtKode'];

$mySql = "SELECT * FROM gejala WHERE kd_gejala='$Kode'";

$myQry = mysql_query($mySql, $koneksidb) or die ("Query ambil

data salah : ".mysql_error());

$myData = mysql_fetch_array($myQry);

// Menyimpan data ke variabel temporary (sementara)

$dataKode = $myData['kd_gejala'];

$dataNama = isset($_POST['txtNama']) ? $_POST['txtNama'] :

$myData['nm_gejala'];

?>

<script type="text/javascript">

function harusangka(jumlah){

var karakter = (jumlah.which) ? jumlah.which : event.keyCode

if (karakter > 31 && (karakter < 46 || karakter > 57))

return (false);

return (true);

}

</script>

Page 150: untuk memenuhi sebagian persyaratan mencapai derajat

131

<link href="../../../../style/style.css" rel="stylesheet" type="text/css" />

<div class="add">

<fieldset>

<legend>Edit Gejala : <?php echo $myData['nm_gejala'] ?></legend>

<div ></div>

<form action="?main=updategejala" method="post"

name="form1">

<table class="table-list" width="100%">

<tr>

<th colspan="3">UBAH GEJALA </th>

</tr>

<tr>

<td width="15%"><b>Kode</b></td>

<td width="1%"><b>:</b></td>

<td width="84%"><input name="textfield" value="<?php echo

$dataKode; ?>" size="8" maxlength="4" readonly="readonly"/>

<input name="txtKode" type="hidden" value="<?php echo

$dataKode; ?>" /></td></tr>

<tr>

<td><b>Nama Gejala </b></td>

<td><b>:</b></td>

<td><input name="txtNama" type="text" value="<?php echo

$dataNama; ?>" size="80" maxlength="100" />

<input name="txtLama" type="hidden" value="<?php echo

$myData['nm_gejala']; ?>" /></td></tr>

<tr><td>&nbsp;</td>

<td>&nbsp;</td>

<td><input type="submit" name="btnSimpan" value=" SIMPAN

"></td>

</tr>

Page 151: untuk memenuhi sebagian persyaratan mencapai derajat

132

</table>

</form>

</fieldset>

</div>

c. Gejala

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".thickbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".colorbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<?php

if (isset($_POST['Del'])) {

if ($_POST['cex'] == NULL) {

echo "<script>window.alert('Data yang akan dihapus belum di

pilih')

javascript:history.go(-1);</script>";

Page 152: untuk memenuhi sebagian persyaratan mencapai derajat

133

} else {

$a = join(",", $_POST['cex']);

mysql_query("DELETE FROM gejala WHERE kd_gejala='$a'

");

print "<script>alert('Data berhasil di dihapus');

javascript:history.go(-

1);</script>";

}

}else{

echo "

<div class=judul><h2>Berikut detail data Gejala:</h2></div>

<br/>

<form action='' method='post'>

<div style='float:right; padding:10px; width:250px; margin-top:5px;'>

<a class='thickbox' href='main/main_gejala/add_gejala.php'>Add

Daftar Gejala</a>

<input type='submit' name='Del' value='Hapus' onclick='return

confirmDelete();'>

</div><br/>

<table id=o width=100%><tbody>

<tr>

<th width='1%' class=th>no</th>

<th width='7%' class=th>Kode Gejala</th>

<th width='13%' class=th>Nama Gejala</th>

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'>ubah</span></div></th>

Page 153: untuk memenuhi sebagian persyaratan mencapai derajat

134

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'><input type='checkbox'

name='checkbox[]' class='checkall'></span></div></th>

</tr>";

$p = new Paging;

$batas = 15;

$posisi = $p->cariPosisi($batas);

$tampil=mysql_query("SELECT * FROM gejala order by

kd_gejala desc LIMIT $posisi,$batas");

$i = 0;

$i = $posisi;

while ($r=mysql_fetch_array($tampil)){

if (($i % 2) > 0)

$bg = '#ffffff'; else

$bg = '#cccccc';

echo "<tr bgcolor=" . $bg . ">

<td class=td align=center>" . ++$i ."</td>

<td class=td>$r[kd_gejala]</td>

<td class=td>$r[nm_gejala]</td>

<td><div align='center' style='background-

color:none;'><a class='colorbox'

href=main/main_gejala/edit_gejala.php?Kode=" . $r['kd_gejala'] . "

><img src='../images/edit.png' border='0' width='16' height='16'

/></a></div></td>

<td><div align='center'><input type='checkbox' name='cex[]'

value='" . $r['kd_gejala'] . "'></div></td>

</tr></tr>";

}

echo "</tbody></table></form>";

Page 154: untuk memenuhi sebagian persyaratan mencapai derajat

135

$sql_pagging = mysql_query("SELECT COUNT(*) AS jml FROM

gejala");

$pagging = mysql_fetch_array($sql_pagging);

$jml = $pagging['jml'];

echo"

</br>

<div class='results'> <span>Jumlah Data : $jml</span><br/><br/>

";

$jmldata = mysql_num_rows(mysql_query("SELECT * from

gejala"));

$jmlhalaman = $p->jumlahHalaman($jmldata, $batas);

$linkHalaman = $p->navHalaman($_GET['halaman'], $jmlhalaman);

echo" Halaman : $linkHalaman </div>";

}

?>

d. Proses_addgejala

<?php

require "../../config/koneksi.php";

# Tombol Simpan diklik

if(isset($_POST['btnSimpan'])){

# Baca Variabel Form

$txtNama = $_POST['txtNama'];

# Validasi form, jika kosong sampaikan pesan error

$pesanError = array();

if (trim($txtNama)=="") {

Page 155: untuk memenuhi sebagian persyaratan mencapai derajat

136

$pesanError[] = "Data <b>Nama Gejala</b> tidak boleh

kosong !";

}

# Validasi Nama gejala, jika sudah ada akan ditolak

$cekSql="SELECT * FROM gejala WHERE

nm_gejala='$txtNama'";

$cekQry=mysql_query($cekSql, $koneksidb) or die ("Eror

Query".mysql_error());

if(mysql_num_rows($cekQry)>=1){

$pesanError[] = "Maaf, Gejala <b> $txtNama </b> sudah

ada, ganti dengan yang lain";

}

# JIKA ADA PESAN ERROR DARI VALIDASI

if (count($pesanError)>=1 ){

echo "<div class='mssgBox'>";

echo "<img src='../images/attention.png'> <br><hr>";

$noPesan=0;

foreach ($pesanError as $indeks=>$pesan_tampil) {

$noPesan++;

echo "&nbsp;&nbsp; $noPesan.

$pesan_tampil<br>";

}

echo "</div> <br>";

}

else {

# SIMPAN DATA KE DATABASE.

// Jika tidak menemukan error, simpan data ke database

$kodeBaru = buatKode("gejala", "E");

Page 156: untuk memenuhi sebagian persyaratan mencapai derajat

137

$mySql = "INSERT INTO gejala (kd_gejala,

nm_gejala) VALUES ('$kodeBaru', '$txtNama')";

$myQry = mysql_query($mySql, $koneksidb) or die

("Gagal query".mysql_error());

if($myQry){

echo "<meta http-equiv='refresh' content='0;

url=?main=gejala'>";

}

exit;

}

} // Penutup Tombol Simpan

?>

e. Proses_updategejala

<?php

require "../../config/koneksi.php";

# Tombol Simpan diklik

if(isset($_POST['btnSimpan'])){

# Baca Variabel Form

$txtNama = $_POST['txtNama'];

# Validasi form, jika kosong sampaikan pesan error

$pesanError = array();

if (trim($txtNama)=="") {

$pesanError[] = "Data <b>Nama Gejala</b> tidak boleh

kosong !";

}

# Validasi Nama gejala, jika sudah ada akan ditolak

$cekSql="SELECT * FROM gejala WHERE

nm_gejala='$txtNama' AND

NOT(nm_gejala='".$_POST['txtLama']."')";

Page 157: untuk memenuhi sebagian persyaratan mencapai derajat

138

$cekQry=mysql_query($cekSql, $koneksidb) or die ("Eror

Query".mysql_error());

if(mysql_num_rows($cekQry)>=1){

$pesanError[] = "Maaf, Gejala <b> $txtNama </b> sudah

ada, ganti dengan yang lain";

}

# JIKA ADA PESAN ERROR DARI VALIDASI

if (count($pesanError)>=1 ){

echo "<div class='mssgBox'>";

echo "<img src='../images/attention.png'> <br><hr>";

$noPesan=0;

foreach ($pesanError as $indeks=>$pesan_tampil) {

$noPesan++;

echo "&nbsp;&nbsp; $noPesan.

$pesan_tampil<br>";

}

echo "</div> <br>";

}

else {

# SIMPAN PERUBAHAN DATA, Jika jumlah error

pesanError tidak ada, simpan datanya

$Kode = $_POST['txtKode'];

$mySql = "UPDATE gejala SET

nm_gejala='$txtNama' WHERE kd_gejala ='$Kode'";

$myQry = mysql_query($mySql, $koneksidb) or die

("Gagal query".mysql_error());

if($myQry){

echo "<meta http-equiv='refresh' content='0;

url=?main=gejala'>";

}

Page 158: untuk memenuhi sebagian persyaratan mencapai derajat

139

exit;

}

} // Penutup Tombol Simpan

?>

4.4.8 Main_hasildiagnosa

a. Cetak

<?php

session_start();

require "../../../../config/koneksi.php";

$NOIP = $_GET['id'];

$sql = "SELECT diagnosa.*, pasien.* , penyakit.*

FROM diagnosa,pasien,penyakit

WHERE pasien.idpasien=diagnosa.idpasien

AND diagnosa.idpasien='$NOIP' AND

diagnosa.kd_penyakit=penyakit.kd_penyakit

ORDER BY diagnosa.idpasien DESC LIMIT 1";

$qry = mysql_query($sql, $koneksidb)

or die ("Query Hasil salam".mysql_error());

$data1= mysql_fetch_array($qry);

?>

<html>

<head>

<title>Hasil Analisa Pasien</title>

<style type="text/css">

<!--

.style1 {

color: #FFFFFF;

font-weight: bold;

Page 159: untuk memenuhi sebagian persyaratan mencapai derajat

140

}

-->

</style>

</head>

<body>

<table width="100%" border="0" cellpadding="2" cellspacing="1"

bgcolor="#DBEAF5">

<tr align="center" bgcolor="#0099CC">

<td height="35" colspan="2" align="left" valign="top"><div

align="center">

<h3 class="style1">Laporan Hasil Dianogsa </h3>

</div></td>

</tr>

<tr>

<td colspan="2"><b>DATA :</b></td>

</tr>

<tr bgcolor="#FFFFFF">

<td width="188">Nama</td>

<td width="870"><?php echo $data1['nama']; ?></td>

</tr>

<tr bgcolor="#FFFFFF">

<td>Kelamin</td>

<td><?php echo $data1['jenis_kelamin']; ?></td>

</tr>

<tr bgcolor="#FFFFFF">

<td>Usia</td>

<td><?php echo $data1['usia']; ?> Tahun</td>

</tr>

<tr bgcolor="#FFFFFF">

<td>Alamat</td>

<td><?php echo $data1['alamat']; ?></td>

Page 160: untuk memenuhi sebagian persyaratan mencapai derajat

141

</tr>

<tr bgcolor="#FFFFFF">

<td>&nbsp;</td>

<td>&nbsp;</td>

</tr>

<tr>

<td colspan="2"><b>HASIL ANALISA TERAKHIR :</b></td>

</tr>

<tr bgcolor="#FFFFFF">

<td>Penyakit</td>

<td><?php echo $data1['nm_penyakit']; ?></td>

</tr>

<tr bgcolor="#FFFFFF">

<td valign="top">Penyebab </td>

<td><?php echo $data1['pencegahan']; ?></td>

</tr>

<tr bgcolor="#FFFFFF">

<td valign="top">Solusi</td>

<td><?php echo $data1['pengobatan']; ?></td>

</tr>

</table>

</body>

</html>

b. Hasildiagnosa

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".thickbox").colorbox({width:"50%",

height:"75%"});

Page 161: untuk memenuhi sebagian persyaratan mencapai derajat

142

});

</script>

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".colorbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<?php

if (isset($_POST['Del'])) {

if ($_POST['cex'] == NULL) {

echo "<script>window.alert('Data yang akan dihapus belum di

pilih')

javascript:history.go(-1);</script>";

} else {

$a = join(",", $_POST['cex']);

$tampil=mysql_query("SELECT * FROM pasien

Where idpasien='$a'");

while($r=mysql_fetch_array($tampil)){

//unlink("../../../gambar/small_$r[gambar]");

}

mysql_query("DELETE FROM pasien WHERE idpasien='$a'");

print "<script>alert('Data berhasil di dihapus');

javascript:history.go(-

1);</script>";

Page 162: untuk memenuhi sebagian persyaratan mencapai derajat

143

}

}else{

echo "

<div class=judul><h2>Berikut Detail Data Hasil Diagnosa:</h2></div>

<br/>

<form action='' method='post'>

<div style='float:right; padding:10px; width:100px; margin-top:5px;'>

<input type='submit' name='Del' value='Hapus' onclick='return

confirmDelete();'>

</div><br/>

<table id=o width=100%><tbody>

<tr>

<th width='1%' class=th>no</th>

<th width='5%' class=th>Nama</th>

<th width='1%' class=th>Jenis Kelamin</th>

<th width='1%' class=th>Usia</th>

<th width='10%' class=th>Alamat</th>

<th width='1%' class=th>Lihat Diagnosa</th>

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'><input type='checkbox'

name='checkbox[]' class='checkall'></span></div></th>

</tr>";

$p = new Paging;

$batas = 15;

$posisi = $p->cariPosisi($batas);

$tampil=mysql_query("SELECT * FROM pasien order by

idpasien desc LIMIT $posisi,$batas");

$no=1;

$i = $posisi;

while ($r=mysql_fetch_array($tampil)){

Page 163: untuk memenuhi sebagian persyaratan mencapai derajat

144

if (($no % 2) > 0)

$bg = '#FFFFFF'; else

$bg = '#cccccc';

echo "<tr bgcolor=" . $bg . "><td class=td align=center>$no</td>

<td class=td>$r[nama]</td>

<td class=td>$r[jenis_kelamin]</td>

<td class=td>$r[usia]</td>

<td class=td>$r[alamat]</td>

<td align='center' class=td><div align='center'

style='background-color:none;'><a class='colorbox'

href=main/main_hasildiagnosa/cetak.php?id=" . $r['idpasien'] . " ><img

src='../images/dt.png' border='0' width='16' height='16' title='Lihat Hasil

Diagnosa' /></a></div></td>

<td><div align='center'><input type='checkbox' name='cex[]'

value='" . $r['idpasien'] . "'></div></td>

</tr></tr>";

$no++;

}

echo "</tbody></table></form>";

$sql_pagging = mysql_query("SELECT COUNT(*) AS jml FROM

pasien");

$pagging = mysql_fetch_array($sql_pagging);

$jml = $pagging['jml'];

echo"

</br>

<div class='results'> <span>Jumlah Data : $jml</span><br/><br/>

";

Page 164: untuk memenuhi sebagian persyaratan mencapai derajat

145

$jmldata = mysql_num_rows(mysql_query("SELECT * from

pasien"));

$jmlhalaman = $p->jumlahHalaman($jmldata, $batas);

$linkHalaman = $p->navHalaman($_GET['halaman'], $jmlhalaman);

echo" Halaman : $linkHalaman </div>";

}

?>

4.4.9 Main_laporan

a. Class.ezpdf

<?php

include_once('class.pdf.php');

class Cezpdf extends Cpdf {

//==================================================

============================

// this class will take the basic interaction facilities of the Cpdf class

// and make more useful functions so that the user does not have to

// know all the ins and outs of pdf presentation to produce something

pretty.

//

// IMPORTANT NOTE

// there is no warranty, implied or otherwise with this software.

//

// version 009 (versioning is linked to class.pdf.php)

//

// released under a public domain licence.

//

// Wayne Munro, R&OS Ltd, http://www.ros.co.nz/pdf

Page 165: untuk memenuhi sebagian persyaratan mencapai derajat

146

//==================================================

============================

var $ez=array('fontSize'=>10); // used for storing most of the page

configuration parameters

var $y; // this is the current vertical positon on the page of the writing

point, very important

var $ezPages=array(); // keep an array of the ids of the pages, making it

easy to go back and add page numbers etc.

var $ezPageCount=0;

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

function Cezpdf($paper='a4',$orientation='portrait'){

// Assuming that people don't want to specify the paper size using

the absolute coordinates

// allow a couple of options:

// orientation can be 'portrait' or 'landscape'

// or, to actually set the coordinates, then pass an array in as the

first parameter.

// the defaults are as shown.

//

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

// 2002-07-24 - Nicola Asuni ([email protected]):

// Added new page formats (45 standard ISO paper formats and 4

american common formats)

// paper cordinates are calculated in this way: (inches * 72) where 1

inch = 2.54 cm

//

// Now you may also pass a 2 values array containing the page

width and height in centimeters

Page 166: untuk memenuhi sebagian persyaratan mencapai derajat

147

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

if (!is_array($paper)){

switch (strtoupper($paper)){

case '4A0': {$size = array(0,0,4767.87,6740.79);

break;}

case '2A0': {$size = array(0,0,3370.39,4767.87);

break;}

case 'A0': {$size = array(0,0,2383.94,3370.39);

break;}

case 'A1': {$size = array(0,0,1683.78,2383.94);

break;}

case 'A2': {$size = array(0,0,1190.55,1683.78);

break;}

case 'A3': {$size = array(0,0,841.89,1190.55);

break;}

case 'A4': default: {$size =

array(0,0,595.28,841.89); break;}

case 'A5': {$size = array(0,0,419.53,595.28);

break;}

case 'A6': {$size = array(0,0,297.64,419.53);

break;}

case 'A7': {$size = array(0,0,209.76,297.64);

break;}

case 'A8': {$size = array(0,0,147.40,209.76);

break;}

case 'A9': {$size = array(0,0,104.88,147.40);

break;}

case 'A10': {$size = array(0,0,73.70,104.88);

break;}

Page 167: untuk memenuhi sebagian persyaratan mencapai derajat

148

case 'B0': {$size = array(0,0,2834.65,4008.19);

break;}

case 'B1': {$size = array(0,0,2004.09,2834.65);

break;}

case 'B2': {$size = array(0,0,1417.32,2004.09);

break;}

case 'B3': {$size = array(0,0,1000.63,1417.32);

break;}

case 'B4': {$size = array(0,0,708.66,1000.63);

break;}

case 'B5': {$size = array(0,0,498.90,708.66);

break;}

case 'B6': {$size = array(0,0,354.33,498.90);

break;}

case 'B7': {$size = array(0,0,249.45,354.33);

break;}

case 'B8': {$size = array(0,0,175.75,249.45);

break;}

case 'B9': {$size = array(0,0,124.72,175.75);

break;}

case 'B10': {$size = array(0,0,87.87,124.72);

break;}

case 'C0': {$size = array(0,0,2599.37,3676.54);

break;}

case 'C1': {$size = array(0,0,1836.85,2599.37);

break;}

case 'C2': {$size = array(0,0,1298.27,1836.85);

break;}

case 'C3': {$size = array(0,0,918.43,1298.27);

break;}

Page 168: untuk memenuhi sebagian persyaratan mencapai derajat

149

case 'C4': {$size = array(0,0,649.13,918.43);

break;}

case 'C5': {$size = array(0,0,459.21,649.13);

break;}

case 'C6': {$size = array(0,0,323.15,459.21);

break;}

case 'C7': {$size = array(0,0,229.61,323.15);

break;}

case 'C8': {$size = array(0,0,161.57,229.61);

break;}

case 'C9': {$size = array(0,0,113.39,161.57);

break;}

case 'C10': {$size = array(0,0,79.37,113.39);

break;}

case 'RA0': {$size = array(0,0,2437.80,3458.27);

break;}

case 'RA1': {$size = array(0,0,1729.13,2437.80);

break;}

case 'RA2': {$size = array(0,0,1218.90,1729.13);

break;}

case 'RA3': {$size = array(0,0,864.57,1218.90);

break;}

case 'RA4': {$size = array(0,0,609.45,864.57);

break;}

case 'SRA0': {$size = array(0,0,2551.18,3628.35);

break;}

case 'SRA1': {$size = array(0,0,1814.17,2551.18);

break;}

case 'SRA2': {$size = array(0,0,1275.59,1814.17);

break;}

Page 169: untuk memenuhi sebagian persyaratan mencapai derajat

150

case 'SRA3': {$size = array(0,0,907.09,1275.59);

break;}

case 'SRA4': {$size = array(0,0,637.80,907.09);

break;}

case 'LETTER': {$size = array(0,0,612.00,792.00);

break;}

case 'LEGAL': {$size = array(0,0,612.00,1008.00);

break;}

case 'EXECUTIVE': {$size =

array(0,0,521.86,756.00); break;}

case 'FOLIO': {$size = array(0,0,612.00,936.00);

break;}

}

switch (strtolower($orientation)){

case 'landscape':

$a=$size[3];

$size[3]=$size[2];

$size[2]=$a;

break;

}

} else {

if (count($paper)>2) {

// then an array was sent it to set the size

$size = $paper;

}

else { //size in centimeters has been passed

$size[0] = 0;

$size[1] = 0;

$size[2] = ( $paper[0] / 2.54 ) * 72;

$size[3] = ( $paper[1] / 2.54 ) * 72;

}

Page 170: untuk memenuhi sebagian persyaratan mencapai derajat

151

}

$this->Cpdf($size);

$this->ez['pageWidth']=$size[2];

$this->ez['pageHeight']=$size[3];

// also set the margins to some reasonable defaults

$this->ez['topMargin']=30;

$this->ez['bottomMargin']=30;

$this->ez['leftMargin']=30;

$this->ez['rightMargin']=30;

// set the current writing position to the top of the first page

$this->y = $this->ez['pageHeight']-$this->ez['topMargin'];

// and get the ID of the page that was created during the instancing

process.

$this->ezPages[1]=$this->getFirstPageId();

$this->ezPageCount=1;

}

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

// 2002-07-24: Nicola Asuni ([email protected])

// Set Margins in centimeters

function ezSetCmMargins($top,$bottom,$left,$right){

$top = ( $top / 2.54 ) * 72;

$bottom = ( $bottom / 2.54 ) * 72;

$left = ( $left / 2.54 ) * 72;

$right = ( $right / 2.54 ) * 72;

$this->ezSetMargins($top,$bottom,$left,$right);

}

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

Page 171: untuk memenuhi sebagian persyaratan mencapai derajat

152

function ezColumnsStart($options=array()){

// start from the current y-position, make the set number of columne

if (isset($this->ez['columns']) && $this->ez['columns']==1){

// if we are already in a column mode then just return.

return;

}

$def=array('gap'=>10,'num'=>2);

foreach($def as $k=>$v){

if (!isset($options[$k])){

$options[$k]=$v;

}

}

// setup the columns

$this->ez['columns']=array('on'=>1,'colNum'=>1);

// store the current margins

$this->ez['columns']['margins']=array(

$this->ez['leftMargin']

,$this->ez['rightMargin']

,$this->ez['topMargin']

,$this->ez['bottomMargin']

);

// and store the settings for the columns

$this->ez['columns']['options']=$options;

// then reset the margins to suit the new columns

// safe enough to assume the first column here, but start from the

current y-position

$this->ez['topMargin']=$this->ez['pageHeight']-$this->y;

Page 172: untuk memenuhi sebagian persyaratan mencapai derajat

153

$width=($this->ez['pageWidth']-$this->ez['leftMargin']-$this-

>ez['rightMargin']-($options['num']-

1)*$options['gap'])/$options['num'];

$this->ez['columns']['width']=$width;

$this->ez['rightMargin']=$this->ez['pageWidth']-$this-

>ez['leftMargin']-$width;

}

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

function ezColumnsStop(){

if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){

$this->ez['columns']['on']=0;

$this->ez['leftMargin']=$this->ez['columns']['margins'][0];

$this->ez['rightMargin']=$this->ez['columns']['margins'][1];

$this->ez['topMargin']=$this->ez['columns']['margins'][2];

$this->ez['bottomMargin']=$this->ez['columns']['margins'][3];

}

}

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

function ezInsertMode($status=1,$pageNum=1,$pos='before'){

// puts the document into insert mode. new pages are inserted until this

is re-called with status=0

// by default pages wil be inserted at the start of the document

switch($status){

case '1':

if (isset($this->ezPages[$pageNum])){

$this->ez['insertMode']=1;

$this->ez['insertOptions']=array('id'=>$this-

>ezPages[$pageNum],'pos'=>$pos);

}

break;

Page 173: untuk memenuhi sebagian persyaratan mencapai derajat

154

case '0':

$this->ez['insertMode']=0;

break;

}

}

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

function ezNewPage(){

$pageRequired=1;

if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){

// check if this is just going to a new column

// increment the column number

//echo 'HERE<br>';

$this->ez['columns']['colNum']++;

//echo $this->ez['columns']['colNum'].'<br>';

if ($this->ez['columns']['colNum'] <= $this-

>ez['columns']['options']['num']){

// then just reset to the top of the next column

$pageRequired=0;

} else {

$this->ez['columns']['colNum']=1;

$this->ez['topMargin']=$this->ez['columns']['margins'][2];

}

$width = $this->ez['columns']['width'];

$this->ez['leftMargin']=$this->ez['columns']['margins'][0]+($this-

>ez['columns']['colNum']-1)*($this-

>ez['columns']['options']['gap']+$width);

$this->ez['rightMargin']=$this->ez['pageWidth']-$this-

>ez['leftMargin']-$width;

}

Page 174: untuk memenuhi sebagian persyaratan mencapai derajat

155

//echo 'left='.$this->ez['leftMargin'].' right='.$this-

>ez['rightMargin'].'<br>';

if ($pageRequired){

// make a new page, setting the writing point back to the top

$this->y = $this->ez['pageHeight']-$this->ez['topMargin'];

// make the new page with a call to the basic class.

$this->ezPageCount++;

if (isset($this->ez['insertMode']) && $this->ez['insertMode']==1){

$id = $this->ezPages[$this->ezPageCount] = $this-

>newPage(1,$this->ez['insertOptions']['id'],$this-

>ez['insertOptions']['pos']);

// then manipulate the insert options so that inserted pages follow

each other

$this->ez['insertOptions']['id']=$id;

$this->ez['insertOptions']['pos']='after';

} else {

$this->ezPages[$this->ezPageCount] = $this->newPage();

}

} else {

$this->y = $this->ez['pageHeight']-$this->ez['topMargin'];

}

}

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

function ezSetMargins($top,$bottom,$left,$right){

// sets the margins to new values

$this->ez['topMargin']=$top;

$this->ez['bottomMargin']=$bottom;

$this->ez['leftMargin']=$left;

Page 175: untuk memenuhi sebagian persyaratan mencapai derajat

156

$this->ez['rightMargin']=$right;

// check to see if this means that the current writing position is outside

the

// writable area

if ($this->y > $this->ez['pageHeight']-$top){

// then move y down

$this->y = $this->ez['pageHeight']-$top;

}

if ( $this->y < $bottom){

// then make a new page

$this->ezNewPage();

}

}

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

function ezGetCurrentPageNumber(){

// return the strict numbering (1,2,3,4..) number of the current page

return $this->ezPageCount;

}

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

function

ezStartPageNumbers($x,$y,$size,$pos='left',$pattern='{PAGENUM} of

{TOTALPAGENUM}',$num=''){

// put page numbers on the pages from here.

// place then on the 'pos' side of the coordinates (x,y).

// pos can be 'left' or 'right'

// use the given 'pattern' for display, where (PAGENUM} and

{TOTALPAGENUM} are replaced

Page 176: untuk memenuhi sebagian persyaratan mencapai derajat

157

// as required.

// if $num is set, then make the first page this number, the number of

total pages will

// be adjusted to account for this.

// Adjust this function so that each time you 'start' page numbers then

you effectively start a different batch

// return the number of the batch, so that they can be stopped in a

different order if required.

if (!$pos || !strlen($pos)){

$pos='left';

}

if (!$pattern || !strlen($pattern)){

$pattern='{PAGENUM} of {TOTALPAGENUM}';

}

if (!isset($this->ez['pageNumbering'])){

$this->ez['pageNumbering']=array();

}

$i = count($this->ez['pageNumbering']);

$this->ez['pageNumbering'][$i][$this-

>ezPageCount]=array('x'=>$x,'y'=>$y,'pos'=>$pos,'pattern'=>$pattern,'

num'=>$num,'size'=>$size);

return $i;

}

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

function ezWhatPageNumber($pageNum,$i=0){

// given a particular generic page number (ie, document numbered

sequentially from beginning),

// return the page number under a particular page numbering scheme

($i)

Page 177: untuk memenuhi sebagian persyaratan mencapai derajat

158

$num=0;

$start=1;

$startNum=1;

if (!isset($this->ez['pageNumbering']))

{

$this->addMessage('WARNING: page numbering called for and

wasn\'t started with ezStartPageNumbers');

return 0;

}

foreach($this->ez['pageNumbering'][$i] as $k=>$v){

if ($k<=$pageNum){

if (is_array($v)){

// start block

if (strlen($v['num'])){

// a start was specified

$start=$v['num'];

$startNum=$k;

$num=$pageNum-$startNum+$start;

}

} else {

// stop block

$num=0;

}

}

}

return $num;

}

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

function ezStopPageNumbers($stopTotal=0,$next=0,$i=0){

Page 178: untuk memenuhi sebagian persyaratan mencapai derajat

159

// if stopTotal=1 then the totalling of pages for this number will stop

too

// if $next=1, then do this page, but not the next, else do not do this

page either

// if $i is set, then stop that particular pagenumbering sequence.

if (!isset($this->ez['pageNumbering'])){

$this->ez['pageNumbering']=array();

}

if ($next && isset($this->ez['pageNumbering'][$i][$this-

>ezPageCount]) && is_array($this->ez['pageNumbering'][$i][$this-

>ezPageCount])){

// then this has only just been started, this will over-write the start,

and nothing will appear

// add a special command to the start block, telling it to stop as well

if ($stopTotal){

$this->ez['pageNumbering'][$i][$this->ezPageCount]['stoptn']=1;

} else {

$this->ez['pageNumbering'][$i][$this->ezPageCount]['stopn']=1;

}

} else {

if ($stopTotal){

$this->ez['pageNumbering'][$i][$this->ezPageCount]='stopt';

} else {

$this->ez['pageNumbering'][$i][$this->ezPageCount]='stop';

}

if ($next){

$this->ez['pageNumbering'][$i][$this->ezPageCount].='n';

}

}

}

Page 179: untuk memenuhi sebagian persyaratan mencapai derajat

160

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

function ezPRVTpageNumberSearch($lbl,&$tmp){

foreach($tmp as $i=>$v){

if (is_array($v)){

if (isset($v[$lbl])){

return $i;

}

} else {

if ($v==$lbl){

return $i;

}

}

}

return 0;

}

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

function ezPRVTaddPageNumbers(){

// this will go through the pageNumbering array and add the page

numbers are required

if (isset($this->ez['pageNumbering'])){

$totalPages1 = $this->ezPageCount;

$tmp1=$this->ez['pageNumbering'];

$status=0;

foreach($tmp1 as $i=>$tmp){

// do each of the page numbering systems

// firstly, find the total pages for this one

$k = $this->ezPRVTpageNumberSearch('stopt',$tmp);

if ($k && $k>0){

Page 180: untuk memenuhi sebagian persyaratan mencapai derajat

161

$totalPages = $k-1;

} else {

$l = $this->ezPRVTpageNumberSearch('stoptn',$tmp);

if ($l && $l>0){

$totalPages = $l;

} else {

$totalPages = $totalPages1;

}

}

foreach ($this->ezPages as $pageNum=>$id){

if (isset($tmp[$pageNum])){

if (is_array($tmp[$pageNum])){

// then this must be starting page numbers

$status=1;

$info = $tmp[$pageNum];

$info['dnum']=$info['num']-$pageNum;

// also check for the special case of the numbering stopping and

starting on the same page

if (isset($info['stopn']) || isset($info['stoptn']) ){

$status=2;

}

} else if ($tmp[$pageNum]=='stop' || $tmp[$pageNum]=='stopt'){

// then we are stopping page numbers

$status=0;

} else if ($status==1 && ($tmp[$pageNum]=='stoptn' ||

$tmp[$pageNum]=='stopn')){

// then we are stopping page numbers

$status=2;

}

}

if ($status){

Page 181: untuk memenuhi sebagian persyaratan mencapai derajat

162

// then add the page numbering to this page

if (strlen($info['num'])){

$num=$pageNum+$info['dnum'];

} else {

$num=$pageNum;

}

$total = $totalPages+$num-$pageNum;

$pat = str_replace('{PAGENUM}',$num,$info['pattern']);

$pat = str_replace('{TOTALPAGENUM}',$total,$pat);

$this->reopenObject($id);

switch($info['pos']){

case 'right':

$this->addText($info['x'],$info['y'],$info['size'],$pat);

break;

default:

$w=$this->getTextWidth($info['size'],$pat);

$this->addText($info['x']-$w,$info['y'],$info['size'],$pat);

break;

}

$this->closeObject();

}

if ($status==2){

$status=0;

}

}

}

}

}

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

Page 182: untuk memenuhi sebagian persyaratan mencapai derajat

163

function ezPRVTcleanUp(){

$this->ezPRVTaddPageNumbers();

}

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

function ezStream($options=''){

$this->ezPRVTcleanUp();

$this->stream($options);

}

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

function ezOutput($options=0){

$this->ezPRVTcleanUp();

return $this->output($options);

}

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

function ezSetY($y){

// used to change the vertical position of the writing point.

$this->y = $y;

if ( $this->y < $this->ez['bottomMargin']){

// then make a new page

$this->ezNewPage();

}

}

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

Page 183: untuk memenuhi sebagian persyaratan mencapai derajat

164

function ezSetDy($dy,$mod=''){

// used to change the vertical position of the writing point.

// changes up by a positive increment, so enter a negative number to go

// down the page

// if $mod is set to 'makeSpace' and a new page is forced, then the

pointed will be moved

// down on the new page, this will allow space to be reserved for

graphics etc.

$this->y += $dy;

if ( $this->y < $this->ez['bottomMargin']){

// then make a new page

$this->ezNewPage();

if ($mod=='makeSpace'){

$this->y += $dy;

}

}

}

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

function

ezPrvtTableDrawLines($pos,$gap,$x0,$x1,$y0,$y1,$y2,$col,$inner,$o

uter,$opt=1){

$x0=1000;

$x1=0;

$this->setStrokeColor($col[0],$col[1],$col[2]);

$cnt=0;

$n = count($pos);

foreach($pos as $x){

$cnt++;

if ($cnt==1 || $cnt==$n){

Page 184: untuk memenuhi sebagian persyaratan mencapai derajat

165

$this->setLineStyle($outer);

} else {

$this->setLineStyle($inner);

}

$this->line($x-$gap/2,$y0,$x-$gap/2,$y2);

if ($x>$x1){ $x1=$x; };

if ($x<$x0){ $x0=$x; };

}

$this->setLineStyle($outer);

$this->line($x0-$gap/2-$outer/2,$y0,$x1-$gap/2+$outer/2,$y0);

// only do the second line if it is different to the first, AND each row

does not have

// a line on it.

if ($y0!=$y1 && $opt<2){

$this->line($x0-$gap/2,$y1,$x1-$gap/2,$y1);

}

$this->line($x0-$gap/2-$outer/2,$y2,$x1-$gap/2+$outer/2,$y2);

}

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

function

ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decende

r,$gap,$size,&$y,$optionsAll=array()){

// uses ezText to add the text, and returns the height taken by the

largest heading

// this page will move the headings to a new page if they will not fit

completely on this one

// transaction support will be used to implement this

if (isset($optionsAll['cols'])){

Page 185: untuk memenuhi sebagian persyaratan mencapai derajat

166

$options = $optionsAll['cols'];

} else {

$options = array();

}

$mx=0;

$startPage = $this->ezPageCount;

$secondGo=0;

// $y is the position at which the top of the table should start, so the

base

// of the first text, is $y-$height-$gap-$decender, but ezText starts by

dropping $height

// the return from this function is the total cell height, including gaps,

and $y is adjusted

// to be the postion of the bottom line

// begin the transaction

$this->transaction('start');

$ok=0;

// $y-=$gap-$decender;

$y-=$gap;

while ($ok==0){

foreach($cols as $colName=>$colHeading){

$this->ezSetY($y);

if (isset($options[$colName]) &&

isset($options[$colName]['justification'])){

$justification = $options[$colName]['justification'];

} else {

$justification = 'left';

Page 186: untuk memenuhi sebagian persyaratan mencapai derajat

167

}

$this->ezText($colHeading,$size,array('aleft'=>

$pos[$colName],'aright'=>($maxWidth[$colName]+$pos[$colName]),'j

ustification'=>$justification));

$dy = $y-$this->y;

if ($dy>$mx){

$mx=$dy;

}

}

$y = $y - $mx - $gap + $decender;

// $y -= $mx-$gap+$decender;

// now, if this has moved to a new page, then abort the transaction,

move to a new page, and put it there

// do not check on the second time around, to avoid an infinite loop

if ($this->ezPageCount != $startPage && $secondGo==0){

$this->transaction('rewind');

$this->ezNewPage();

$y = $this->y - $gap-$decender;

$ok=0;

$secondGo=1;

// $y = $store_y;

$mx=0;

} else {

$this->transaction('commit');

$ok=1;

}

}

return $mx+$gap*2-$decender;

Page 187: untuk memenuhi sebagian persyaratan mencapai derajat

168

}

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

function ezPrvtGetTextWidth($size,$text){

// will calculate the maximum width, taking into account that the text

may be broken

// by line breaks.

$mx=0;

$lines = explode("\n",$text);

foreach ($lines as $line){

$w = $this->getTextWidth($size,$line);

if ($w>$mx){

$mx=$w;

}

}

return $mx;

}

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

function ezTable(&$data,$cols='',$title='',$options=''){

// add a table of information to the pdf document

// $data is a two dimensional array

// $cols (optional) is an associative array, the keys are the names of the

columns from $data

// to be presented (and in that order), the values are the titles to be

given to the columns

// $title (optional) is the title to be put on the top of the table

//

// $options is an associative array which can contain:

Page 188: untuk memenuhi sebagian persyaratan mencapai derajat

169

// 'showLines'=> 0,1,2, default is 1 (show outside and top lines only),

2=> lines on each row

// 'showHeadings' => 0 or 1

// 'shaded'=> 0,1,2,3 default is 1 (1->alternate lines are shaded, 0->no

shading, 2-> both shaded, second uses shadeCol2)

// 'shadeCol' => (r,g,b) array, defining the colour of the shading,

default is (0.8,0.8,0.8)

// 'shadeCol2' => (r,g,b) array, defining the colour of the shading of the

other blocks, default is (0.7,0.7,0.7)

// 'fontSize' => 10

// 'textCol' => (r,g,b) array, text colour

// 'titleFontSize' => 12

// 'rowGap' => 2 , the space added at the top and bottom of each row,

between the text and the lines

// 'colGap' => 5 , the space on the left and right sides of each cell

// 'lineCol' => (r,g,b) array, defining the colour of the lines, default,

black.

// 'xPos' => 'left','right','center','centre',or coordinate, reference

coordinate in the x-direction

// 'xOrientation' => 'left','right','center','centre', position of the table

w.r.t 'xPos'

// 'width'=> <number> which will specify the width of the table, if it

turns out to not be this

// wide, then it will stretch the table to fit, if it is wider then each cell

will be made

// proportionalty smaller, and the content may have to wrap.

// 'maxWidth'=> <number> similar to 'width', but will only make table

smaller than it wants to be

// 'options' =>

array(<colname>=>array('justification'=>'left','width'=>100,'link'=>link

DataName),<colname>=>....)

Page 189: untuk memenuhi sebagian persyaratan mencapai derajat

170

// allow the setting of other paramaters for the individual

columns

// 'minRowSpace'=> the minimum space between the bottom of each

row and the bottom margin, in which a new row will be started

// if it is less, then a new page would be started, default=-

100

// 'innerLineThickness'=>1

// 'outerLineThickness'=>1

// 'splitRows'=>0, 0 or 1, whether or not to allow the rows to be split

across page boundaries

// 'protectRows'=>number, the number of rows to hold with the

heading on page, ie, if there less than this number of

// rows on the page, then move the whole lot onto the next

page, default=1

//

// note that the user will have had to make a font selection already or

this will not

// produce a valid pdf file.

if (!is_array($data)){

return;

}

if (!is_array($cols)){

// take the columns from the first row of the data set

reset($data);

list($k,$v)=each($data);

if (!is_array($v)){

return;

}

$cols=array();

Page 190: untuk memenuhi sebagian persyaratan mencapai derajat

171

foreach($v as $k1=>$v1){

$cols[$k1]=$k1;

}

}

if (!is_array($options)){

$options=array();

}

$defaults = array(

'shaded'=>1,'showLines'=>1,'shadeCol'=>array(0.8,0.8,0.8),'shadeCol2'

=>array(0.7,0.7,0.7),'fontSize'=>10,'titleFontSize'=>12

,'titleGap'=>5,'lineCol'=>array(0,0,0),'gap'=>5,'xPos'=>'centre','xOrient

ation'=>'centre'

,'showHeadings'=>1,'textCol'=>array(0,0,0),'width'=>0,'maxWidth'=>0,'

cols'=>array(),'minRowSpace'=>-100,'rowGap'=>2,'colGap'=>5

,'innerLineThickness'=>1,'outerLineThickness'=>1,'splitRows'=>0,'prot

ectRows'=>1

);

foreach($defaults as $key=>$value){

if (is_array($value)){

if (!isset($options[$key]) || !is_array($options[$key])){

$options[$key]=$value;

}

} else {

if (!isset($options[$key])){

Page 191: untuk memenuhi sebagian persyaratan mencapai derajat

172

$options[$key]=$value;

}

}

}

$options['gap']=2*$options['colGap'];

$middle = ($this->ez['pageWidth']-$this->ez['rightMargin'])/2+($this-

>ez['leftMargin'])/2;

// figure out the maximum widths of the text within each column

$maxWidth=array();

foreach($cols as $colName=>$colHeading){

$maxWidth[$colName]=0;

}

// find the maximum cell widths based on the data

foreach($data as $row){

foreach($cols as $colName=>$colHeading){

$w = $this-

>ezPrvtGetTextWidth($options['fontSize'],(string)$row[$colName])*1.

01;

if ($w > $maxWidth[$colName]){

$maxWidth[$colName]=$w;

}

}

}

// and the maximum widths to fit in the headings

foreach($cols as $colName=>$colTitle){

$w = $this-

>ezPrvtGetTextWidth($options['fontSize'],(string)$colTitle)*1.01;

if ($w > $maxWidth[$colName]){

$maxWidth[$colName]=$w;

}

Page 192: untuk memenuhi sebagian persyaratan mencapai derajat

173

}

// calculate the start positions of each of the columns

$pos=array();

$x=0;

$t=$x;

$adjustmentWidth=0;

$setWidth=0;

foreach($maxWidth as $colName => $w){

$pos[$colName]=$t;

// if the column width has been specified then set that here, also total

the

// width avaliable for adjustment

if (isset($options['cols'][$colName]) &&

isset($options['cols'][$colName]['width']) &&

$options['cols'][$colName]['width']>0){

$t=$t+$options['cols'][$colName]['width'];

$maxWidth[$colName] = $options['cols'][$colName]['width']-

$options['gap'];

$setWidth += $options['cols'][$colName]['width'];

} else {

$t=$t+$w+$options['gap'];

$adjustmentWidth += $w;

$setWidth += $options['gap'];

}

}

$pos['_end_']=$t;

// if maxWidth is specified, and the table is too wide, and the width

has not been set,

// then set the width.

Page 193: untuk memenuhi sebagian persyaratan mencapai derajat

174

if ($options['width']==0 && $options['maxWidth'] && ($t-

$x)>$options['maxWidth']){

// then need to make this one smaller

$options['width']=$options['maxWidth'];

}

if ($options['width'] && $adjustmentWidth>0 &&

$setWidth<$options['width']){

// first find the current widths of the columns involved in this mystery

$cols0 = array();

$cols1 = array();

$xq=0;

$presentWidth=0;

$last='';

foreach($pos as $colName=>$p){

if (!isset($options['cols'][$last]) ||

!isset($options['cols'][$last]['width']) ||

$options['cols'][$last]['width']<=0){

if (strlen($last)){

$cols0[$last]=$p-$xq -$options['gap'];

$presentWidth += ($p-$xq - $options['gap']);

}

} else {

$cols1[$last]=$p-$xq;

}

$last=$colName;

$xq=$p;

}

// $cols0 contains the widths of all the columns which are not set

$neededWidth = $options['width']-$setWidth;

Page 194: untuk memenuhi sebagian persyaratan mencapai derajat

175

// if needed width is negative then add it equally to each column, else

get more tricky

if ($presentWidth<$neededWidth){

foreach($cols0 as $colName=>$w){

$cols0[$colName]+= ($neededWidth-

$presentWidth)/count($cols0);

}

} else {

$cnt=0;

while ($presentWidth>$neededWidth && $cnt<100){

$cnt++; // insurance policy

// find the widest columns, and the next to widest width

$aWidest = array();

$nWidest=0;

$widest=0;

foreach($cols0 as $colName=>$w){

if ($w>$widest){

$aWidest=array($colName);

$nWidest = $widest;

$widest=$w;

} else if ($w==$widest){

$aWidest[]=$colName;

}

}

// then figure out what the width of the widest columns would have

to be to take up all the slack

$newWidestWidth = $widest - ($presentWidth-

$neededWidth)/count($aWidest);

if ($newWidestWidth > $nWidest){

// then there is space to set them to this

Page 195: untuk memenuhi sebagian persyaratan mencapai derajat

176

foreach($aWidest as $colName){

$cols0[$colName] = $newWidestWidth;

}

$presentWidth=$neededWidth;

} else {

// there is not space, reduce the size of the widest ones down to

the next size down, and we

// will go round again

foreach($aWidest as $colName){

$cols0[$colName] = $nWidest;

}

$presentWidth=$presentWidth-($widest-

$nWidest)*count($aWidest);

}

}

}

// $cols0 now contains the new widths of the constrained columns.

// now need to update the $pos and $maxWidth arrays

$xq=0;

foreach($pos as $colName=>$p){

$pos[$colName]=$xq;

if (!isset($options['cols'][$colName]) ||

!isset($options['cols'][$colName]['width']) ||

$options['cols'][$colName]['width']<=0){

if (isset($cols0[$colName])){

$xq += $cols0[$colName] + $options['gap'];

$maxWidth[$colName]=$cols0[$colName];

}

} else {

if (isset($cols1[$colName])){

$xq += $cols1[$colName];

Page 196: untuk memenuhi sebagian persyaratan mencapai derajat

177

}

}

}

$t=$x+$options['width'];

$pos['_end_']=$t;

}

// now adjust the table to the correct location across the page

switch ($options['xPos']){

case 'left':

$xref = $this->ez['leftMargin'];

break;

case 'right':

$xref = $this->ez['pageWidth'] - $this->ez['rightMargin'];

break;

case 'centre':

case 'center':

$xref = $middle;

break;

default:

$xref = $options['xPos'];

break;

}

switch ($options['xOrientation']){

case 'left':

$dx = $xref-$t;

break;

case 'right':

$dx = $xref;

break;

Page 197: untuk memenuhi sebagian persyaratan mencapai derajat

178

case 'centre':

case 'center':

$dx = $xref-$t/2;

break;

}

foreach($pos as $k=>$v){

$pos[$k]=$v+$dx;

}

$x0=$x+$dx;

$x1=$t+$dx;

$baseLeftMargin = $this->ez['leftMargin'];

$basePos = $pos;

$baseX0 = $x0;

$baseX1 = $x1;

// ok, just about ready to make me a table

$this-

>setColor($options['textCol'][0],$options['textCol'][1],$options['textCol

'][2]);

$this-

>setStrokeColor($options['shadeCol'][0],$options['shadeCol'][1],$optio

ns['shadeCol'][2]);

$middle = ($x1+$x0)/2;

// start a transaction which will be used to regress the table, if there are

not enough rows protected

if ($options['protectRows']>0){

Page 198: untuk memenuhi sebagian persyaratan mencapai derajat

179

$this->transaction('start');

$movedOnce=0;

}

$abortTable = 1;

while ($abortTable){

$abortTable=0;

$dm = $this->ez['leftMargin']-$baseLeftMargin;

foreach($basePos as $k=>$v){

$pos[$k]=$v+$dm;

}

$x0=$baseX0+$dm;

$x1=$baseX1+$dm;

$middle = ($x1+$x0)/2;

// if the title is set, then do that

if (strlen($title)){

$w = $this->getTextWidth($options['titleFontSize'],$title);

$this->y -= $this->getFontHeight($options['titleFontSize']);

if ($this->y < $this->ez['bottomMargin']){

$this->ezNewPage();

// margins may have changed on the newpage

$dm = $this->ez['leftMargin']-$baseLeftMargin;

foreach($basePos as $k=>$v){

$pos[$k]=$v+$dm;

}

$x0=$baseX0+$dm;

$x1=$baseX1+$dm;

$middle = ($x1+$x0)/2;

$this->y -= $this->getFontHeight($options['titleFontSize']);

Page 199: untuk memenuhi sebagian persyaratan mencapai derajat

180

}

$this->addText($middle-$w/2,$this-

>y,$options['titleFontSize'],$title);

$this->y -= $options['titleGap'];

}

// margins may have changed on the newpage

$dm = $this->ez['leftMargin']-$baseLeftMargin;

foreach($basePos as $k=>$v){

$pos[$k]=$v+$dm;

}

$x0=$baseX0+$dm;

$x1=$baseX1+$dm;

$y=$this->y; // to simplify the code a bit

// make the table

$height = $this->getFontHeight($options['fontSize']);

$decender = $this->getFontDecender($options['fontSize']);

$y0=$y+$decender;

$dy=0;

if ($options['showHeadings']){

// this function will move the start of the table to a new page if it does

not fit on this one

$headingHeight = $this-

>ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decend

er,$options['rowGap'],$options['fontSize'],$y,$options);

$y0 = $y+$headingHeight;

Page 200: untuk memenuhi sebagian persyaratan mencapai derajat

181

$y1 = $y;

$dm = $this->ez['leftMargin']-$baseLeftMargin;

foreach($basePos as $k=>$v){

$pos[$k]=$v+$dm;

}

$x0=$baseX0+$dm;

$x1=$baseX1+$dm;

} else {

$y1 = $y0;

}

$firstLine=1;

// open an object here so that the text can be put in over the shading

if ($options['shaded']){

$this->saveState();

$textObjectId = $this->openObject();

$this->closeObject();

$this->addObject($textObjectId);

$this->reopenObject($textObjectId);

}

$cnt=0;

$newPage=0;

foreach($data as $row){

$cnt++;

// the transaction support will be used to prevent rows being split

if ($options['splitRows']==0){

Page 201: untuk memenuhi sebagian persyaratan mencapai derajat

182

$pageStart = $this->ezPageCount;

if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){

$columnStart = $this->ez['columns']['colNum'];

}

$this->transaction('start');

$row_orig = $row;

$y_orig = $y;

$y0_orig = $y0;

$y1_orig = $y1;

}

$ok=0;

$secondTurn=0;

while(!$abortTable && $ok == 0){

$mx=0;

$newRow=1;

while(!$abortTable && ($newPage || $newRow)){

$y-=$height;

if ($newPage || $y<$this->ez['bottomMargin'] ||

(isset($options['minRowSpace']) && $y<($this-

>ez['bottomMargin']+$options['minRowSpace'])) ){

// check that enough rows are with the heading

if ($options['protectRows']>0 && $movedOnce==0 &&

$cnt<=$options['protectRows']){

// then we need to move the whole table onto the next page

$movedOnce = 1;

$abortTable = 1;

}

$y2=$y-$mx+2*$height+$decender-$newRow*$height;

Page 202: untuk memenuhi sebagian persyaratan mencapai derajat

183

if ($options['showLines']){

if (!$options['showHeadings']){

$y0=$y1;

}

$this-

>ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$op

tions['lineCol'],$options['innerLineThickness'],$options['outerLineThic

kness'],$options['showLines']);

}

if ($options['shaded']){

$this->closeObject();

$this->restoreState();

}

$this->ezNewPage();

// and the margins may have changed, this is due to the possibility

of the columns being turned on

// as the columns are managed by manipulating the margins

$dm = $this->ez['leftMargin']-$baseLeftMargin;

foreach($basePos as $k=>$v){

$pos[$k]=$v+$dm;

}

// $x0=$x0+$dm;

// $x1=$x1+$dm;

$x0=$baseX0+$dm;

$x1=$baseX1+$dm;

if ($options['shaded']){

$this->saveState();

$textObjectId = $this->openObject();

$this->closeObject();

Page 203: untuk memenuhi sebagian persyaratan mencapai derajat

184

$this->addObject($textObjectId);

$this->reopenObject($textObjectId);

}

$this-

>setColor($options['textCol'][0],$options['textCol'][1],$options['textCol

'][2],1);

$y = $this->ez['pageHeight']-$this->ez['topMargin'];

$y0=$y+$decender;

$mx=0;

if ($options['showHeadings']){

$this-

>ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decend

er,$options['rowGap'],$options['fontSize'],$y,$options);

$y1=$y;

} else {

$y1=$y0;

}

$firstLine=1;

$y -= $height;

}

$newRow=0;

// write the actual data

// if these cells need to be split over a page, then $newPage will be

set, and the remaining

// text will be placed in $leftOvers

$newPage=0;

$leftOvers=array();

foreach($cols as $colName=>$colTitle){

$this->ezSetY($y+$height);

$colNewPage=0;

Page 204: untuk memenuhi sebagian persyaratan mencapai derajat

185

if (isset($row[$colName])){

if (isset($options['cols'][$colName]) &&

isset($options['cols'][$colName]['link']) &&

strlen($options['cols'][$colName]['link'])){

$lines = explode("\n",$row[$colName]);

if (isset($row[$options['cols'][$colName]['link']]) &&

strlen($row[$options['cols'][$colName]['link']])){

foreach($lines as $k=>$v){

$lines[$k]='<c:alink:'.$row[$options['cols'][$colName]['link']].'>'.$v.'</

c:alink>';

}

}

} else {

$lines = explode("\n",$row[$colName]);

}

} else {

$lines = array();

}

$this->y -= $options['rowGap'];

foreach ($lines as $line){

$line = $this->ezProcessText($line);

$start=1;

while (strlen($line) || $start){

$start=0;

if (!$colNewPage){

$this->y=$this->y-$height;

}

if ($this->y < $this->ez['bottomMargin']){

Page 205: untuk memenuhi sebagian persyaratan mencapai derajat

186

// $this->ezNewPage();

$newPage=1; // whether a new page is required for any of the

columns

$colNewPage=1; // whether a new page is required for this

column

}

if ($colNewPage){

if (isset($leftOvers[$colName])){

$leftOvers[$colName].="\n".$line;

} else {

$leftOvers[$colName] = $line;

}

$line='';

} else {

if (isset($options['cols'][$colName]) &&

isset($options['cols'][$colName]['justification']) ){

$just = $options['cols'][$colName]['justification'];

} else {

$just='left';

}

$line=$this->addTextWrap($pos[$colName],$this-

>y,$maxWidth[$colName],$options['fontSize'],$line,$just);

}

}

}

$dy=$y+$height-$this->y+$options['rowGap'];

if ($dy-$height*$newPage>$mx){

$mx=$dy-$height*$newPage;

}

Page 206: untuk memenuhi sebagian persyaratan mencapai derajat

187

}

// set $row to $leftOvers so that they will be processed onto the new

page

$row = $leftOvers;

// now add the shading underneath

if ($options['shaded'] && $cnt%2==0){

$this->closeObject();

$this-

>setColor($options['shadeCol'][0],$options['shadeCol'][1],$options['sha

deCol'][2],1);

$this->filledRectangle($x0-

$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);

$this->reopenObject($textObjectId);

}

if ($options['shaded']==2 && $cnt%2==1){

$this->closeObject();

$this-

>setColor($options['shadeCol2'][0],$options['shadeCol2'][1],$options['s

hadeCol2'][2],1);

$this->filledRectangle($x0-

$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);

$this->reopenObject($textObjectId);

}

if ($options['showLines']>1){

// then draw a line on the top of each block

// $this->closeObject();

$this->saveState();

Page 207: untuk memenuhi sebagian persyaratan mencapai derajat

188

$this-

>setStrokeColor($options['lineCol'][0],$options['lineCol'][1],$options['l

ineCol'][2],1);

// $this->line($x0-$options['gap']/2,$y+$decender+$height-

$mx,$x1-$x0,$mx);

if ($firstLine){

$this->setLineStyle($options['outerLineThickness']);

$firstLine=0;

} else {

$this->setLineStyle($options['innerLineThickness']);

}

$this->line($x0-$options['gap']/2,$y+$decender+$height,$x1-

$options['gap']/2,$y+$decender+$height);

$this->restoreState();

// $this->reopenObject($textObjectId);

}

} // end of while

$y=$y-$mx+$height;

// checking row split over pages

if ($options['splitRows']==0){

if ( ( ($this->ezPageCount != $pageStart) || (isset($this-

>ez['columns']) && $this->ez['columns']['on']==1 && $columnStart !=

$this->ez['columns']['colNum'] )) && $secondTurn==0){

// then we need to go back and try that again !

$newPage=1;

$secondTurn=1;

$this->transaction('rewind');

$row = $row_orig;

$y = $y_orig;

$y0 = $y0_orig;

Page 208: untuk memenuhi sebagian persyaratan mencapai derajat

189

$y1 = $y1_orig;

$ok=0;

$dm = $this->ez['leftMargin']-$baseLeftMargin;

foreach($basePos as $k=>$v){

$pos[$k]=$v+$dm;

}

$x0=$baseX0+$dm;

$x1=$baseX1+$dm;

} else {

$this->transaction('commit');

$ok=1;

}

} else {

$ok=1; // don't go round the loop if splitting rows is allowed

}

} // end of while to check for row splitting

if ($abortTable){

if ($ok==0){

$this->transaction('abort');

}

// only the outer transaction should be operational

$this->transaction('rewind');

$this->ezNewPage();

break;

}

} // end of foreach ($data as $row)

Page 209: untuk memenuhi sebagian persyaratan mencapai derajat

190

} // end of while ($abortTable)

// table has been put on the page, the rows guarded as required,

commit.

$this->transaction('commit');

$y2=$y+$decender;

if ($options['showLines']){

if (!$options['showHeadings']){

$y0=$y1;

}

$this-

>ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$op

tions['lineCol'],$options['innerLineThickness'],$options['outerLineThic

kness'],$options['showLines']);

}

// close the object for drawing the text on top

if ($options['shaded']){

$this->closeObject();

$this->restoreState();

}

$this->y=$y;

return $y;

}

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

function ezProcessText($text){

// this function will intially be used to implement underlining support,

but could be used for a range of other

Page 210: untuk memenuhi sebagian persyaratan mencapai derajat

191

// purposes

$search = array('<u>','<U>','</u>','</U>');

$replace = array('<c:uline>','<c:uline>','</c:uline>','</c:uline>');

return str_replace($search,$replace,$text);

}

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

function ezText($text,$size=0,$options=array(),$test=0){

// this will add a string of text to the document, starting at the current

drawing

// position.

// it will wrap to keep within the margins, including optional offsets

from the left

// and the right, if $size is not specified, then it will be the last one

used, or

// the default value (12 I think).

// the text will go to the start of the next line when a return code "\n" is

found.

// possible options are:

// 'left'=> number, gap to leave from the left margin

// 'right'=> number, gap to leave from the right margin

// 'aleft'=> number, absolute left position (overrides 'left')

// 'aright'=> number, absolute right position (overrides 'right')

// 'justification' => 'left','right','center','centre','full'

// only set one of the next two items (leading overrides spacing)

// 'leading' => number, defines the total height taken by the line,

independent of the font height.

// 'spacing' => a real number, though usually set to one of 1, 1.5, 2

(line spacing as used in word processing)

Page 211: untuk memenuhi sebagian persyaratan mencapai derajat

192

// if $test is set then this should just check if the text is going to flow

onto a new page or not, returning true or false

// apply the filtering which will make the underlining function.

$text = $this->ezProcessText($text);

$newPage=false;

$store_y = $this->y;

if (is_array($options) && isset($options['aleft'])){

$left=$options['aleft'];

} else {

$left = $this->ez['leftMargin'] + ((is_array($options) &&

isset($options['left']))?$options['left']:0);

}

if (is_array($options) && isset($options['aright'])){

$right=$options['aright'];

} else {

$right = $this->ez['pageWidth'] - $this->ez['rightMargin'] -

((is_array($options) && isset($options['right']))?$options['right']:0);

}

if ($size<=0){

$size = $this->ez['fontSize'];

} else {

$this->ez['fontSize']=$size;

}

if (is_array($options) && isset($options['justification'])){

$just = $options['justification'];

} else {

Page 212: untuk memenuhi sebagian persyaratan mencapai derajat

193

$just = 'left';

}

// modifications to give leading and spacing based on those given by

Craig Heydenburg 1/1/02

if (is_array($options) && isset($options['leading'])) { ## use leading

instead of spacing

$height = $options['leading'];

} else if (is_array($options) && isset($options['spacing'])) {

$height = $this->getFontHeight($size) * $options['spacing'];

} else {

$height = $this->getFontHeight($size);

}

$lines = explode("\n",$text);

foreach ($lines as $line){

$start=1;

while (strlen($line) || $start){

$start=0;

$this->y=$this->y-$height;

if ($this->y < $this->ez['bottomMargin']){

if ($test){

$newPage=true;

} else {

$this->ezNewPage();

// and then re-calc the left and right, in case they have changed

due to columns

}

}

if (is_array($options) && isset($options['aleft'])){

Page 213: untuk memenuhi sebagian persyaratan mencapai derajat

194

$left=$options['aleft'];

} else {

$left = $this->ez['leftMargin'] + ((is_array($options) &&

isset($options['left']))?$options['left']:0);

}

if (is_array($options) && isset($options['aright'])){

$right=$options['aright'];

} else {

$right = $this->ez['pageWidth'] - $this->ez['rightMargin'] -

((is_array($options) && isset($options['right']))?$options['right']:0);

}

$line=$this->addTextWrap($left,$this->y,$right-

$left,$size,$line,$just,0,$test);

}

}

if ($test){

$this->y=$store_y;

return $newPage;

} else {

return $this->y;

}

}

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

function ezImage($image,$pad = 5,$width = 0,$resize = 'full',$just =

'center',$border = ''){

//beta ezimage function

if (stristr($image,'://'))//copy to temp file

{

Page 214: untuk memenuhi sebagian persyaratan mencapai derajat

195

$fp = @fopen($image,"rb");

while(!feof($fp))

{

$cont.= fread($fp,1024);

}

fclose($fp);

$image = tempnam ("/tmp", "php-pdf");

$fp2 = @fopen($image,"w");

fwrite($fp2,$cont);

fclose($fp2);

$temp = true;

}

if (!(file_exists($image))) return false; //return immediately if

image file does not exist

$imageInfo = getimagesize($image);

switch ($imageInfo[2]){

case 2:

$type = "jpeg";

break;

case 3:

$type = "png";

break;

default:

return false; //return if file is not jpg or png

}

if ($width == 0) $width = $imageInfo[0]; //set width

$ratio = $imageInfo[0]/$imageInfo[1];

//get maximum width of image

if (isset($this->ez['columns']) && $this->ez['columns']['on'] == 1)

Page 215: untuk memenuhi sebagian persyaratan mencapai derajat

196

{

$bigwidth = $this->ez['columns']['width'] - ($pad * 2);

}

else

{

$bigwidth = $this->ez['pageWidth'] - ($pad * 2);

}

//fix width if larger than maximum or if $resize=full

if ($resize == 'full' || $resize == 'width' || $width > $bigwidth)

{

$width = $bigwidth;

}

$height = ($width/$ratio); //set height

//fix size if runs off page

if ($height > ($this->y - $this->ez['bottomMargin'] - ($pad * 2)))

{

if ($resize != 'full')

{

$this->ezNewPage();

}

else

{

$height = ($this->y - $this->ez['bottomMargin'] -

($pad * 2)); //shrink height

$width = ($height*$ratio); //fix width

}

}

Page 216: untuk memenuhi sebagian persyaratan mencapai derajat

197

//fix x-offset if image smaller than bigwidth

if ($width < $bigwidth)

{

//center if justification=center

if ($just == 'center')

{

$offset = ($bigwidth - $width) / 2;

}

//move to right if justification=right

if ($just == 'right')

{

$offset = ($bigwidth - $width);

}

//leave at left if justification=left

if ($just == 'left')

{

$offset = 0;

}

}

//call appropriate function

if ($type == "jpeg"){

$this->addJpegFromFile($image,$this->ez['leftMargin'] +

$pad + $offset, $this->y + $this->getFontHeight($this->ez['fontSize']) -

$pad - $height,$width);

}

if ($type == "png"){

Page 217: untuk memenuhi sebagian persyaratan mencapai derajat

198

$this->addPngFromFile($image,$this->ez['leftMargin'] +

$pad + $offset, $this->y + $this->getFontHeight($this->ez['fontSize']) -

$pad - $height,$width);

}

//draw border

if ($border != '')

{

if (!(isset($border['color'])))

{

$border['color']['red'] = .5;

$border['color']['blue'] = .5;

$border['color']['green'] = .5;

}

if (!(isset($border['width']))) $border['width'] = 1;

if (!(isset($border['cap']))) $border['cap'] = 'round';

if (!(isset($border['join']))) $border['join'] = 'round';

$this-

>setStrokeColor($border['color']['red'],$border['color']['green'],$border[

'color']['blue']);

$this->setLineStyle($border['width'],$border['cap'],$border['join']);

$this->rectangle($this->ez['leftMargin'] + $pad + $offset, $this->y

+ $this->getFontHeight($this->ez['fontSize']) - $pad -

$height,$width,$height);

}

// move y below image

$this->y = $this->y - $pad - $height;

//remove tempfile for remote images

if ($temp == true) unlink($image);

Page 218: untuk memenuhi sebagian persyaratan mencapai derajat

199

}

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

// note that templating code is still considered developmental - have not

really figured

// out a good way of doing this yet.

function loadTemplate($templateFile){

// this function will load the requested template ($file includes full or

relative pathname)

// the code for the template will be modified to make it name safe, and

then stored in

// an array for later use

// The id of the template will be returned for the user to operate on it

later

if (!file_exists($templateFile)){

return -1;

}

$code = implode('',file($templateFile));

if (!strlen($code)){

return;

}

$code = trim($code);

if (substr($code,0,5)=='<?php'){

$code = substr($code,5);

}

if (substr($code,-2)=='?>'){

$code = substr($code,0,strlen($code)-2);

}

Page 219: untuk memenuhi sebagian persyaratan mencapai derajat

200

if (isset($this->ez['numTemplates'])){

$newNum = $this->ez['numTemplates'];

$this->ez['numTemplates']++;

} else {

$newNum=0;

$this->ez['numTemplates']=1;

$this->ez['templates']=array();

}

$this->ez['templates'][$newNum]['code']=$code;

return $newNum;

}

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

function execTemplate($id,$data=array(),$options=array()){

// execute the given template on the current document.

if (!isset($this->ez['templates'][$id])){

return;

}

eval($this->ez['templates'][$id]['code']);

}

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

function ilink($info){

$this->alink($info,1);

}

function alink($info,$internal=0){

Page 220: untuk memenuhi sebagian persyaratan mencapai derajat

201

// a callback function to support the formation of clickable links within

the document

$lineFactor=0.05; // the thickness of the line as a proportion of the

height. also the drop of the line.

switch($info['status']){

case 'start':

case 'sol':

// the beginning of the link

// this should contain the URl for the link as the 'p' entry, and will

also contain the value of 'nCallback'

if (!isset($this->ez['links'])){

$this->ez['links']=array();

}

$i = $info['nCallback'];

$this->ez['links'][$i] =

array('x'=>$info['x'],'y'=>$info['y'],'angle'=>$info['angle'],'decender'=>

$info['decender'],'height'=>$info['height'],'url'=>$info['p']);

if ($internal==0){

$this->saveState();

$this->setColor(0,0,1);

$this->setStrokeColor(0,0,1);

$thick = $info['height']*$lineFactor;

$this->setLineStyle($thick);

}

break;

case 'end':

case 'eol':

// the end of the link

// assume that it is the most recent opening which has closed

$i = $info['nCallback'];

$start = $this->ez['links'][$i];

Page 221: untuk memenuhi sebagian persyaratan mencapai derajat

202

// add underlining

if ($internal){

$this-

>addInternalLink($start['url'],$start['x'],$start['y']+$start['decender'],$in

fo['x'],$start['y']+$start['decender']+$start['height']);

} else {

$a = deg2rad((float)$start['angle']-90.0);

$drop = $start['height']*$lineFactor*1.5;

$dropx = cos($a)*$drop;

$dropy = -sin($a)*$drop;

$this->line($start['x']-$dropx,$start['y']-$dropy,$info['x']-

$dropx,$info['y']-$dropy);

$this-

>addLink($start['url'],$start['x'],$start['y']+$start['decender'],$info['x'],$

start['y']+$start['decender']+$start['height']);

$this->restoreState();

}

break;

}

}

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

function uline($info){

// a callback function to support underlining

$lineFactor=0.05; // the thickness of the line as a proportion of the

height. also the drop of the line.

switch($info['status']){

case 'start':

case 'sol':

Page 222: untuk memenuhi sebagian persyaratan mencapai derajat

203

// the beginning of the underline zone

if (!isset($this->ez['links'])){

$this->ez['links']=array();

}

$i = $info['nCallback'];

$this->ez['links'][$i] =

array('x'=>$info['x'],'y'=>$info['y'],'angle'=>$info['angle'],'decender'=>

$info['decender'],'height'=>$info['height']);

$this->saveState();

$thick = $info['height']*$lineFactor;

$this->setLineStyle($thick);

break;

case 'end':

case 'eol':

// the end of the link

// assume that it is the most recent opening which has closed

$i = $info['nCallback'];

$start = $this->ez['links'][$i];

// add underlining

$a = deg2rad((float)$start['angle']-90.0);

$drop = $start['height']*$lineFactor*1.5;

$dropx = cos($a)*$drop;

$dropy = -sin($a)*$drop;

$this->line($start['x']-$dropx,$start['y']-$dropy,$info['x']-

$dropx,$info['y']-$dropy);

$this->restoreState();

break;

}

}

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

Page 223: untuk memenuhi sebagian persyaratan mencapai derajat

204

}

?>

b. Class.pdf

<?php

/**

* Cpdf

*

* http://www.ros.co.nz/pdf

*

* A PHP class to provide the basic functionality to create a pdf

document without

* any requirement for additional modules.

*

* Note that they companion class CezPdf can be used to extend this

class and dramatically

* simplify the creation of documents.

*

* IMPORTANT NOTE

* there is no warranty, implied or otherwise with this software.

*

* LICENCE

* This code has been placed in the Public Domain for all to enjoy.

*

* @author Wayne Munro <[email protected]>

* @version 009

* @package Cpdf

*/

class Cpdf {

/**

Page 224: untuk memenuhi sebagian persyaratan mencapai derajat

205

* the current number of pdf objects in the document

*/

var $numObj=0;

/**

* this array contains all of the pdf objects, ready for final assembly

*/

var $objects = array();

/**

* the objectId (number within the objects array) of the document

catalog

*/

var $catalogId;

/**

* array carrying information about the fonts that the system currently

knows about

* used to ensure that a font is not loaded twice, among other things

*/

var $fonts=array();

/**

* a record of the current font

*/

var $currentFont='';

/**

* the current base font

*/

var $currentBaseFont='';

/**

* the number of the current font within the font array

*/

var $currentFontNum=0;

/**

Page 225: untuk memenuhi sebagian persyaratan mencapai derajat

206

*

*/

var $currentNode;

/**

* object number of the current page

*/

var $currentPage;

/**

* object number of the currently active contents block

*/

var $currentContents;

/**

* number of fonts within the system

*/

var $numFonts=0;

/**

* current colour for fill operations, defaults to inactive value, all three

components should be between 0 and 1 inclusive when active

*/

var $currentColour=array('r'=>-1,'g'=>-1,'b'=>-1);

/**

* current colour for stroke operations (lines etc.)

*/

var $currentStrokeColour=array('r'=>-1,'g'=>-1,'b'=>-1);

/**

* current style that lines are drawn in

*/

var $currentLineStyle='';

/**

* an array which is used to save the state of the document, mainly the

colours and styles

Page 226: untuk memenuhi sebagian persyaratan mencapai derajat

207

* it is used to temporarily change to another state, the change back to

what it was before

*/

var $stateStack = array();

/**

* number of elements within the state stack

*/

var $nStateStack = 0;

/**

* number of page objects within the document

*/

var $numPages=0;

/**

* object Id storage stack

*/

var $stack=array();

/**

* number of elements within the object Id storage stack

*/

var $nStack=0;

/**

* an array which contains information about the objects which are not

firmly attached to pages

* these have been added with the addObject function

*/

var $looseObjects=array();

/**

* array contains infomation about how the loose objects are to be added

to the document

*/

var $addLooseObjects=array();

Page 227: untuk memenuhi sebagian persyaratan mencapai derajat

208

/**

* the objectId of the information object for the document

* this contains authorship, title etc.

*/

var $infoObject=0;

/**

* number of images being tracked within the document

*/

var $numImages=0;

/**

* an array containing options about the document

* it defaults to turning on the compression of the objects

*/

var $options=array('compression'=>1);

/**

* the objectId of the first page of the document

*/

var $firstPageId;

/**

* used to track the last used value of the inter-word spacing, this is so

that it is known

* when the spacing is changed.

*/

var $wordSpaceAdjust=0;

/**

* the object Id of the procset object

*/

var $procsetObjectId;

/**

* store the information about the relationship between font families

Page 228: untuk memenuhi sebagian persyaratan mencapai derajat

209

* this used so that the code knows which font is the bold version of

another font, etc.

* the value of this array is initialised in the constuctor function.

*/

var $fontFamilies = array();

/**

* track if the current font is bolded or italicised

*/

var $currentTextState = '';

/**

* messages are stored here during processing, these can be selected

afterwards to give some useful debug information

*/

var $messages='';

/**

* the ancryption array for the document encryption is stored here

*/

var $arc4='';

/**

* the object Id of the encryption information

*/

var $arc4_objnum=0;

/**

* the file identifier, used to uniquely identify a pdf document

*/

var $fileIdentifier='';

/**

* a flag to say if a document is to be encrypted or not

*/

var $encrypted=0;

/**

Page 229: untuk memenuhi sebagian persyaratan mencapai derajat

210

* the ancryption key for the encryption of all the document content

(structure is not encrypted)

*/

var $encryptionKey='';

/**

* array which forms a stack to keep track of nested callback functions

*/

var $callback = array();

/**

* the number of callback functions in the callback array

*/

var $nCallback = 0;

/**

* store label->id pairs for named destinations, these will be used to

replace internal links

* done this way so that destinations can be defined after the location

that links to them

*/

var $destinations = array();

/**

* store the stack for the transaction commands, each item in here is a

record of the values of all the

* variables within the class, so that the user can rollback at will (from

each 'start' command)

* note that this includes the objects array, so these can be large.

*/

var $checkpoint = '';

/**

* class constructor

* this will start a new document

Page 230: untuk memenuhi sebagian persyaratan mencapai derajat

211

* @var array array of 4 numbers, defining the bottom left and upper

right corner of the page. first two are normally zero.

*/

function Cpdf ($pageSize=array(0,0,612,792)){

$this->newDocument($pageSize);

// also initialize the font families that are known about already

$this->setFontFamily('init');

// $this->fileIdentifier = md5('xxxxxxxx'.time());

}

/**

* Document object methods (internal use only)

*

* There is about one object method for each type of object in the pdf

document

* Each function has the same call list ($id,$action,$options).

* $id = the object ID of the object, or what it is to be if it is being

created

* $action = a string specifying the action to be performed, though ALL

must support:

* 'new' - create the object with the id $id

* 'out' - produce the output for the pdf object

* $options = optional, a string or array containing the various

parameters for the object

*

* These, in conjunction with the output function are the ONLY way for

output to be produced

* within the pdf 'file'.

*/

Page 231: untuk memenuhi sebagian persyaratan mencapai derajat

212

/**

*destination object, used to specify the location for the user to jump to,

presently on opening

*/

function o_destination($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch($action){

case 'new':

$this->objects[$id]=array('t'=>'destination','info'=>array());

$tmp = '';

switch ($options['type']){

case 'XYZ':

case 'FitR':

$tmp = ' '.$options['p3'].$tmp;

case 'FitH':

case 'FitV':

case 'FitBH':

case 'FitBV':

$tmp = ' '.$options['p1'].' '.$options['p2'].$tmp;

case 'Fit':

case 'FitB':

$tmp = $options['type'].$tmp;

$this->objects[$id]['info']['string']=$tmp;

$this->objects[$id]['info']['page']=$options['page'];

}

break;

case 'out':

$tmp = $o['info'];

Page 232: untuk memenuhi sebagian persyaratan mencapai derajat

213

$res="\n".$id." 0 obj\n".'['.$tmp['page'].' 0 R

/'.$tmp['string']."]\nendobj\n";

return $res;

break;

}

}

/**

* set the viewer preferences

*/

function o_viewerPreferences($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->objects[$id]=array('t'=>'viewerPreferences','info'=>array());

break;

case 'add':

foreach($options as $k=>$v){

switch ($k){

case 'HideToolbar':

case 'HideMenubar':

case 'HideWindowUI':

case 'FitWindow':

case 'CenterWindow':

case 'NonFullScreenPageMode':

case 'Direction':

$o['info'][$k]=$v;

break;

}

Page 233: untuk memenuhi sebagian persyaratan mencapai derajat

214

}

break;

case 'out':

$res="\n".$id." 0 obj\n".'<< ';

foreach($o['info'] as $k=>$v){

$res.="\n/".$k.' '.$v;

}

$res.="\n>>\n";

return $res;

break;

}

}

/**

* define the document catalog, the overall controller for the document

*/

function o_catalog($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->objects[$id]=array('t'=>'catalog','info'=>array());

$this->catalogId=$id;

break;

case 'outlines':

case 'pages':

case 'openHere':

$o['info'][$action]=$options;

break;

Page 234: untuk memenuhi sebagian persyaratan mencapai derajat

215

case 'viewerPreferences':

if (!isset($o['info']['viewerPreferences'])){

$this->numObj++;

$this->o_viewerPreferences($this->numObj,'new');

$o['info']['viewerPreferences']=$this->numObj;

}

$vp = $o['info']['viewerPreferences'];

$this->o_viewerPreferences($vp,'add',$options);

break;

case 'out':

$res="\n".$id." 0 obj\n".'<< /Type /Catalog';

foreach($o['info'] as $k=>$v){

switch($k){

case 'outlines':

$res.="\n".'/Outlines '.$v.' 0 R';

break;

case 'pages':

$res.="\n".'/Pages '.$v.' 0 R';

break;

case 'viewerPreferences':

$res.="\n".'/ViewerPreferences '.$o['info']['viewerPreferences'].'

0 R';

break;

case 'openHere':

$res.="\n".'/OpenAction '.$o['info']['openHere'].' 0 R';

break;

}

}

$res.=" >>\nendobj";

return $res;

break;

Page 235: untuk memenuhi sebagian persyaratan mencapai derajat

216

}

}

/**

* object which is a parent to the pages in the document

*/

function o_pages($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->objects[$id]=array('t'=>'pages','info'=>array());

$this->o_catalog($this->catalogId,'pages',$id);

break;

case 'page':

if (!is_array($options)){

// then it will just be the id of the new page

$o['info']['pages'][]=$options;

} else {

// then it should be an array having 'id','rid','pos', where rid=the

page to which this one will be placed relative

// and pos is either 'before' or 'after', saying where this page will fit.

if (isset($options['id']) && isset($options['rid']) &&

isset($options['pos'])){

$i = array_search($options['rid'],$o['info']['pages']);

if (isset($o['info']['pages'][$i]) &&

$o['info']['pages'][$i]==$options['rid']){

// then there is a match

// make a space

switch ($options['pos']){

Page 236: untuk memenuhi sebagian persyaratan mencapai derajat

217

case 'before':

$k = $i;

break;

case 'after':

$k=$i+1;

break;

default:

$k=-1;

break;

}

if ($k>=0){

for ($j=count($o['info']['pages'])-1;$j>=$k;$j--){

$o['info']['pages'][$j+1]=$o['info']['pages'][$j];

}

$o['info']['pages'][$k]=$options['id'];

}

}

}

}

break;

case 'procset':

$o['info']['procset']=$options;

break;

case 'mediaBox':

$o['info']['mediaBox']=$options; // which should be an array of 4

numbers

break;

case 'font':

$o['info']['fonts'][]=array('objNum'=>$options['objNum'],'fontNum'=>$

options['fontNum']);

Page 237: untuk memenuhi sebagian persyaratan mencapai derajat

218

break;

case 'xObject':

$o['info']['xObjects'][]=array('objNum'=>$options['objNum'],'label'=>$

options['label']);

break;

case 'out':

if (count($o['info']['pages'])){

$res="\n".$id." 0 obj\n<< /Type /Pages\n/Kids [";

foreach($o['info']['pages'] as $k=>$v){

$res.=$v." 0 R\n";

}

$res.="]\n/Count ".count($this->objects[$id]['info']['pages']);

if ((isset($o['info']['fonts']) && count($o['info']['fonts'])) ||

isset($o['info']['procset'])){

$res.="\n/Resources <<";

if (isset($o['info']['procset'])){

$res.="\n/ProcSet ".$o['info']['procset']." 0 R";

}

if (isset($o['info']['fonts']) && count($o['info']['fonts'])){

$res.="\n/Font << ";

foreach($o['info']['fonts'] as $finfo){

$res.="\n/F".$finfo['fontNum']." ".$finfo['objNum']." 0 R";

}

$res.=" >>";

}

if (isset($o['info']['xObjects']) && count($o['info']['xObjects'])){

$res.="\n/XObject << ";

foreach($o['info']['xObjects'] as $finfo){

$res.="\n/".$finfo['label']." ".$finfo['objNum']." 0 R";

}

Page 238: untuk memenuhi sebagian persyaratan mencapai derajat

219

$res.=" >>";

}

$res.="\n>>";

if (isset($o['info']['mediaBox'])){

$tmp=$o['info']['mediaBox'];

$res.="\n/MediaBox [".sprintf('%.3f',$tmp[0]).'

'.sprintf('%.3f',$tmp[1]).' '.sprintf('%.3f',$tmp[2]).'

'.sprintf('%.3f',$tmp[3]).']';

}

}

$res.="\n >>\nendobj";

} else {

$res="\n".$id." 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj";

}

return $res;

break;

}

}

/**

* define the outlines in the doc, empty for now

*/

function o_outlines($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this-

>objects[$id]=array('t'=>'outlines','info'=>array('outlines'=>array()));

$this->o_catalog($this->catalogId,'outlines',$id);

Page 239: untuk memenuhi sebagian persyaratan mencapai derajat

220

break;

case 'outline':

$o['info']['outlines'][]=$options;

break;

case 'out':

if (count($o['info']['outlines'])){

$res="\n".$id." 0 obj\n<< /Type /Outlines /Kids [";

foreach($o['info']['outlines'] as $k=>$v){

$res.=$v." 0 R ";

}

$res.="] /Count ".count($o['info']['outlines'])." >>\nendobj";

} else {

$res="\n".$id." 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj";

}

return $res;

break;

}

}

/**

* an object to hold the font description

*/

function o_font($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this-

>objects[$id]=array('t'=>'font','info'=>array('name'=>$options['name'],'

SubType'=>'Type1'));

Page 240: untuk memenuhi sebagian persyaratan mencapai derajat

221

$fontNum=$this->numFonts;

$this->objects[$id]['info']['fontNum']=$fontNum;

// deal with the encoding and the differences

if (isset($options['differences'])){

// then we'll need an encoding dictionary

$this->numObj++;

$this->o_fontEncoding($this->numObj,'new',$options);

$this->objects[$id]['info']['encodingDictionary']=$this->numObj;

} else if (isset($options['encoding'])){

// we can specify encoding here

switch($options['encoding']){

case 'WinAnsiEncoding':

case 'MacRomanEncoding':

case 'MacExpertEncoding':

$this->objects[$id]['info']['encoding']=$options['encoding'];

break;

case 'none':

break;

default:

$this->objects[$id]['info']['encoding']='WinAnsiEncoding';

break;

}

} else {

$this->objects[$id]['info']['encoding']='WinAnsiEncoding';

}

// also tell the pages node about the new font

$this->o_pages($this-

>currentNode,'font',array('fontNum'=>$fontNum,'objNum'=>$id));

break;

case 'add':

foreach ($options as $k=>$v){

Page 241: untuk memenuhi sebagian persyaratan mencapai derajat

222

switch ($k){

case 'BaseFont':

$o['info']['name'] = $v;

break;

case 'FirstChar':

case 'LastChar':

case 'Widths':

case 'FontDescriptor':

case 'SubType':

$this->addMessage('o_font '.$k." : ".$v);

$o['info'][$k] = $v;

break;

}

}

break;

case 'out':

$res="\n".$id." 0 obj\n<< /Type /Font\n/Subtype

/".$o['info']['SubType']."\n";

$res.="/Name /F".$o['info']['fontNum']."\n";

$res.="/BaseFont /".$o['info']['name']."\n";

if (isset($o['info']['encodingDictionary'])){

// then place a reference to the dictionary

$res.="/Encoding ".$o['info']['encodingDictionary']." 0 R\n";

} else if (isset($o['info']['encoding'])){

// use the specified encoding

$res.="/Encoding /".$o['info']['encoding']."\n";

}

if (isset($o['info']['FirstChar'])){

$res.="/FirstChar ".$o['info']['FirstChar']."\n";

}

if (isset($o['info']['LastChar'])){

Page 242: untuk memenuhi sebagian persyaratan mencapai derajat

223

$res.="/LastChar ".$o['info']['LastChar']."\n";

}

if (isset($o['info']['Widths'])){

$res.="/Widths ".$o['info']['Widths']." 0 R\n";

}

if (isset($o['info']['FontDescriptor'])){

$res.="/FontDescriptor ".$o['info']['FontDescriptor']." 0 R\n";

}

$res.=">>\nendobj";

return $res;

break;

}

}

/**

* a font descriptor, needed for including additional fonts

*/

function o_fontDescriptor($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->objects[$id]=array('t'=>'fontDescriptor','info'=>$options);

break;

case 'out':

$res="\n".$id." 0 obj\n<< /Type /FontDescriptor\n";

foreach ($o['info'] as $label => $value){

switch ($label){

case 'Ascent':

case 'CapHeight':

Page 243: untuk memenuhi sebagian persyaratan mencapai derajat

224

case 'Descent':

case 'Flags':

case 'ItalicAngle':

case 'StemV':

case 'AvgWidth':

case 'Leading':

case 'MaxWidth':

case 'MissingWidth':

case 'StemH':

case 'XHeight':

case 'CharSet':

if (strlen($value)){

$res.='/'.$label.' '.$value."\n";

}

break;

case 'FontFile':

case 'FontFile2':

case 'FontFile3':

$res.='/'.$label.' '.$value." 0 R\n";

break;

case 'FontBBox':

$res.='/'.$label.' ['.$value[0].' '.$value[1].' '.$value[2].'

'.$value[3]."]\n";

break;

case 'FontName':

$res.='/'.$label.' /'.$value."\n";

break;

}

}

$res.=">>\nendobj";

return $res;

Page 244: untuk memenuhi sebagian persyaratan mencapai derajat

225

break;

}

}

/**

* the font encoding

*/

function o_fontEncoding($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

// the options array should contain 'differences' and maybe

'encoding'

$this->objects[$id]=array('t'=>'fontEncoding','info'=>$options);

break;

case 'out':

$res="\n".$id." 0 obj\n<< /Type /Encoding\n";

if (!isset($o['info']['encoding'])){

$o['info']['encoding']='WinAnsiEncoding';

}

if ($o['info']['encoding']!='none'){

$res.="/BaseEncoding /".$o['info']['encoding']."\n";

}

$res.="/Differences \n[";

$onum=-100;

foreach($o['info']['differences'] as $num=>$label){

if ($num!=$onum+1){

// we cannot make use of consecutive numbering

$res.= "\n".$num." /".$label;

Page 245: untuk memenuhi sebagian persyaratan mencapai derajat

226

} else {

$res.= " /".$label;

}

$onum=$num;

}

$res.="\n]\n>>\nendobj";

return $res;

break;

}

}

/**

* the document procset, solves some problems with printing to old PS

printers

*/

function o_procset($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this-

>objects[$id]=array('t'=>'procset','info'=>array('PDF'=>1,'Text'=>1));

$this->o_pages($this->currentNode,'procset',$id);

$this->procsetObjectId=$id;

break;

case 'add':

// this is to add new items to the procset list, despite the fact that this

is considered

// obselete, the items are required for printing to some postscript

printers

Page 246: untuk memenuhi sebagian persyaratan mencapai derajat

227

switch ($options) {

case 'ImageB':

case 'ImageC':

case 'ImageI':

$o['info'][$options]=1;

break;

}

break;

case 'out':

$res="\n".$id." 0 obj\n[";

foreach ($o['info'] as $label=>$val){

$res.='/'.$label.' ';

}

$res.="]\nendobj";

return $res;

break;

}

}

/**

* define the document information

*/

function o_info($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->infoObject=$id;

$date='D:'.date('Ymd');

Page 247: untuk memenuhi sebagian persyaratan mencapai derajat

228

$this->objects[$id]=array('t'=>'info','info'=>array('Creator'=>'R and

OS php pdf writer, http://www.ros.co.nz','CreationDate'=>$date));

break;

case 'Title':

case 'Author':

case 'Subject':

case 'Keywords':

case 'Creator':

case 'Producer':

case 'CreationDate':

case 'ModDate':

case 'Trapped':

$o['info'][$action]=$options;

break;

case 'out':

if ($this->encrypted){

$this->encryptInit($id);

}

$res="\n".$id." 0 obj\n<<\n";

foreach ($o['info'] as $k=>$v){

$res.='/'.$k.' (';

if ($this->encrypted){

$res.=$this->filterText($this->ARC4($v));

} else {

$res.=$this->filterText($v);

}

$res.=")\n";

}

$res.=">>\nendobj";

return $res;

break;

Page 248: untuk memenuhi sebagian persyaratan mencapai derajat

229

}

}

/**

* an action object, used to link to URLS initially

*/

function o_action($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

if (is_array($options)){

$this-

>objects[$id]=array('t'=>'action','info'=>$options,'type'=>$options['type

']);

} else {

// then assume a URI action

$this-

>objects[$id]=array('t'=>'action','info'=>$options,'type'=>'URI');

}

break;

case 'out':

if ($this->encrypted){

$this->encryptInit($id);

}

$res="\n".$id." 0 obj\n<< /Type /Action";

switch($o['type']){

case 'ilink':

// there will be an 'label' setting, this is the name of the destination

Page 249: untuk memenuhi sebagian persyaratan mencapai derajat

230

$res.="\n/S /GoTo\n/D ".$this-

>destinations[(string)$o['info']['label']]." 0 R";

break;

case 'URI':

$res.="\n/S /URI\n/URI (";

if ($this->encrypted){

$res.=$this->filterText($this->ARC4($o['info']));

} else {

$res.=$this->filterText($o['info']);

}

$res.=")";

break;

}

$res.="\n>>\nendobj";

return $res;

break;

}

}

/**

* an annotation object, this will add an annotation to the current page.

* initially will support just link annotations

*/

function o_annotation($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

// add the annotation to the current page

$pageId = $this->currentPage;

Page 250: untuk memenuhi sebagian persyaratan mencapai derajat

231

$this->o_page($pageId,'annot',$id);

// and add the action object which is going to be required

switch($options['type']){

case 'link':

$this->objects[$id]=array('t'=>'annotation','info'=>$options);

$this->numObj++;

$this->o_action($this->numObj,'new',$options['url']);

$this->objects[$id]['info']['actionId']=$this->numObj;

break;

case 'ilink':

// this is to a named internal link

$label = $options['label'];

$this->objects[$id]=array('t'=>'annotation','info'=>$options);

$this->numObj++;

$this->o_action($this-

>numObj,'new',array('type'=>'ilink','label'=>$label));

$this->objects[$id]['info']['actionId']=$this->numObj;

break;

}

break;

case 'out':

$res="\n".$id." 0 obj\n<< /Type /Annot";

switch($o['info']['type']){

case 'link':

case 'ilink':

$res.= "\n/Subtype /Link";

break;

}

$res.="\n/A ".$o['info']['actionId']." 0 R";

$res.="\n/Border [0 0 0]";

$res.="\n/H /I";

Page 251: untuk memenuhi sebagian persyaratan mencapai derajat

232

$res.="\n/Rect [ ";

foreach($o['info']['rect'] as $v){

$res.= sprintf("%.4f ",$v);

}

$res.="]";

$res.="\n>>\nendobj";

return $res;

break;

}

}

/**

* a page object, it also creates a contents object to hold its contents

*/

function o_page($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->numPages++;

$this->objects[$id]=array('t'=>'page','info'=>array('parent'=>$this-

>currentNode,'pageNum'=>$this->numPages));

if (is_array($options)){

// then this must be a page insertion, array shoudl contain

'rid','pos'=[before|after]

$options['id']=$id;

$this->o_pages($this->currentNode,'page',$options);

} else {

$this->o_pages($this->currentNode,'page',$id);

}

Page 252: untuk memenuhi sebagian persyaratan mencapai derajat

233

$this->currentPage=$id;

//make a contents object to go with this page

$this->numObj++;

$this->o_contents($this->numObj,'new',$id);

$this->currentContents=$this->numObj;

$this->objects[$id]['info']['contents']=array();

$this->objects[$id]['info']['contents'][]=$this->numObj;

$match = ($this->numPages%2 ? 'odd' : 'even');

foreach($this->addLooseObjects as $oId=>$target){

if ($target=='all' || $match==$target){

$this->objects[$id]['info']['contents'][]=$oId;

}

}

break;

case 'content':

$o['info']['contents'][]=$options;

break;

case 'annot':

// add an annotation to this page

if (!isset($o['info']['annot'])){

$o['info']['annot']=array();

}

// $options should contain the id of the annotation dictionary

$o['info']['annot'][]=$options;

break;

case 'out':

$res="\n".$id." 0 obj\n<< /Type /Page";

$res.="\n/Parent ".$o['info']['parent']." 0 R";

if (isset($o['info']['annot'])){

$res.="\n/Annots [";

foreach($o['info']['annot'] as $aId){

Page 253: untuk memenuhi sebagian persyaratan mencapai derajat

234

$res.=" ".$aId." 0 R";

}

$res.=" ]";

}

$count = count($o['info']['contents']);

if ($count==1){

$res.="\n/Contents ".$o['info']['contents'][0]." 0 R";

} else if ($count>1){

$res.="\n/Contents [\n";

foreach ($o['info']['contents'] as $cId){

$res.=$cId." 0 R\n";

}

$res.="]";

}

$res.="\n>>\nendobj";

return $res;

break;

}

}

/**

* the contents objects hold all of the content which appears on pages

*/

function o_contents($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch ($action){

case 'new':

$this->objects[$id]=array('t'=>'contents','c'=>'','info'=>array());

if (strlen($options) && intval($options)){

Page 254: untuk memenuhi sebagian persyaratan mencapai derajat

235

// then this contents is the primary for a page

$this->objects[$id]['onPage']=$options;

} else if ($options=='raw'){

// then this page contains some other type of system object

$this->objects[$id]['raw']=1;

}

break;

case 'add':

// add more options to the decleration

foreach ($options as $k=>$v){

$o['info'][$k]=$v;

}

case 'out':

$tmp=$o['c'];

$res= "\n".$id." 0 obj\n";

if (isset($this->objects[$id]['raw'])){

$res.=$tmp;

} else {

$res.= "<<";

if (function_exists('gzcompress') && $this-

>options['compression']){

// then implement ZLIB based compression on this content stream

$res.=" /Filter /FlateDecode";

$tmp = gzcompress($tmp);

}

if ($this->encrypted){

$this->encryptInit($id);

$tmp = $this->ARC4($tmp);

}

foreach($o['info'] as $k=>$v){

$res .= "\n/".$k.' '.$v;

Page 255: untuk memenuhi sebagian persyaratan mencapai derajat

236

}

$res.="\n/Length ".strlen($tmp)."

>>\nstream\n".$tmp."\nendstream";

}

$res.="\nendobj\n";

return $res;

break;

}

}

/**

* an image object, will be an XObject in the document, includes

description and data

*/

function o_image($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch($action){

case 'new':

// make the new object

$this-

>objects[$id]=array('t'=>'image','data'=>$options['data'],'info'=>array())

;

$this->objects[$id]['info']['Type']='/XObject';

$this->objects[$id]['info']['Subtype']='/Image';

$this->objects[$id]['info']['Width']=$options['iw'];

$this->objects[$id]['info']['Height']=$options['ih'];

if (!isset($options['type']) || $options['type']=='jpg'){

if (!isset($options['channels'])){

$options['channels']=3;

Page 256: untuk memenuhi sebagian persyaratan mencapai derajat

237

}

switch($options['channels']){

case 1:

$this->objects[$id]['info']['ColorSpace']='/DeviceGray';

break;

default:

$this->objects[$id]['info']['ColorSpace']='/DeviceRGB';

break;

}

$this->objects[$id]['info']['Filter']='/DCTDecode';

$this->objects[$id]['info']['BitsPerComponent']=8;

} else if ($options['type']=='png'){

$this->objects[$id]['info']['Filter']='/FlateDecode';

$this->objects[$id]['info']['DecodeParms']='<< /Predictor 15

/Colors '.$options['ncolor'].' /Columns '.$options['iw'].'

/BitsPerComponent '.$options['bitsPerComponent'].'>>';

if (strlen($options['pdata'])){

$tmp = ' [ /Indexed /DeviceRGB '.(strlen($options['pdata'])/3-1).'

';

$this->numObj++;

$this->o_contents($this->numObj,'new');

$this->objects[$this->numObj]['c']=$options['pdata'];

$tmp.=$this->numObj.' 0 R';

$tmp .=' ]';

$this->objects[$id]['info']['ColorSpace'] = $tmp;

if (isset($options['transparency'])){

switch($options['transparency']['type']){

case 'indexed':

$tmp=' [ '.$options['transparency']['data'].'

'.$options['transparency']['data'].'] ';

$this->objects[$id]['info']['Mask'] = $tmp;

Page 257: untuk memenuhi sebagian persyaratan mencapai derajat

238

break;

}

}

} else {

$this->objects[$id]['info']['ColorSpace']='/'.$options['color'];

}

$this-

>objects[$id]['info']['BitsPerComponent']=$options['bitsPerComponent'

];

}

// assign it a place in the named resource dictionary as an external

object, according to

// the label passed in with it.

$this->o_pages($this-

>currentNode,'xObject',array('label'=>$options['label'],'objNum'=>$id))

;

// also make sure that we have the right procset object for it.

$this->o_procset($this->procsetObjectId,'add','ImageC');

break;

case 'out':

$tmp=$o['data'];

$res= "\n".$id." 0 obj\n<<";

foreach($o['info'] as $k=>$v){

$res.="\n/".$k.' '.$v;

}

if ($this->encrypted){

$this->encryptInit($id);

$tmp = $this->ARC4($tmp);

}

$res.="\n/Length ".strlen($tmp)."

>>\nstream\n".$tmp."\nendstream\nendobj\n";

Page 258: untuk memenuhi sebagian persyaratan mencapai derajat

239

return $res;

break;

}

}

/**

* encryption object.

*/

function o_encryption($id,$action,$options=''){

if ($action!='new'){

$o =& $this->objects[$id];

}

switch($action){

case 'new':

// make the new object

$this->objects[$id]=array('t'=>'encryption','info'=>$options);

$this->arc4_objnum=$id;

// figure out the additional paramaters required

$pad =

chr(0x28).chr(0xBF).chr(0x4E).chr(0x5E).chr(0x4E).chr(0x75).chr(0x8

A).chr(0x41).chr(0x64).chr(0x00).chr(0x4E).chr(0x56).chr(0xFF).chr(0

xFA).chr(0x01).chr(0x08).chr(0x2E).chr(0x2E).chr(0x00).chr(0xB6).ch

r(0xD0).chr(0x68).chr(0x3E).chr(0x80).chr(0x2F).chr(0x0C).chr(0xA9)

.chr(0xFE).chr(0x64).chr(0x53).chr(0x69).chr(0x7A);

$len = strlen($options['owner']);

if ($len>32){

$owner = substr($options['owner'],0,32);

} else if ($len<32){

$owner = $options['owner'].substr($pad,0,32-$len);

} else {

$owner = $options['owner'];

Page 259: untuk memenuhi sebagian persyaratan mencapai derajat

240

}

$len = strlen($options['user']);

if ($len>32){

$user = substr($options['user'],0,32);

} else if ($len<32){

$user = $options['user'].substr($pad,0,32-$len);

} else {

$user = $options['user'];

}

$tmp = $this->md5_16($owner);

$okey = substr($tmp,0,5);

$this->ARC4_init($okey);

$ovalue=$this->ARC4($user);

$this->objects[$id]['info']['O']=$ovalue;

// now make the u value, phew.

$tmp = $this-

>md5_16($user.$ovalue.chr($options['p']).chr(255).chr(255).chr(255).$

this->fileIdentifier);

$ukey = substr($tmp,0,5);

$this->ARC4_init($ukey);

$this->encryptionKey = $ukey;

$this->encrypted=1;

$uvalue=$this->ARC4($pad);

$this->objects[$id]['info']['U']=$uvalue;

$this->encryptionKey=$ukey;

// initialize the arc4 array

break;

case 'out':

Page 260: untuk memenuhi sebagian persyaratan mencapai derajat

241

$res= "\n".$id." 0 obj\n<<";

$res.="\n/Filter /Standard";

$res.="\n/V 1";

$res.="\n/R 2";

$res.="\n/O (".$this->filterText($o['info']['O']).')';

$res.="\n/U (".$this->filterText($o['info']['U']).')';

// and the p-value needs to be converted to account for the twos-

complement approach

$o['info']['p'] = (($o['info']['p']^255)+1)*-1;

$res.="\n/P ".($o['info']['p']);

$res.="\n>>\nendobj\n";

return $res;

break;

}

}

/**

* ARC4 functions

* A series of function to implement ARC4 encoding in PHP

*/

/**

* calculate the 16 byte version of the 128 bit md5 digest of the string

*/

function md5_16($string){

$tmp = md5($string);

$out='';

for ($i=0;$i<=30;$i=$i+2){

$out.=chr(hexdec(substr($tmp,$i,2)));

}

Page 261: untuk memenuhi sebagian persyaratan mencapai derajat

242

return $out;

}

/**

* initialize the encryption for processing a particular object

*/

function encryptInit($id){

$tmp = $this->encryptionKey;

$hex = dechex($id);

if (strlen($hex)<6){

$hex = substr('000000',0,6-strlen($hex)).$hex;

}

$tmp.=

chr(hexdec(substr($hex,4,2))).chr(hexdec(substr($hex,2,2))).chr(hexdec

(substr($hex,0,2))).chr(0).chr(0);

$key = $this->md5_16($tmp);

$this->ARC4_init(substr($key,0,10));

}

/**

* initialize the ARC4 encryption

*/

function ARC4_init($key=''){

$this->arc4 = '';

// setup the control array

if (strlen($key)==0){

return;

}

$k = '';

while(strlen($k)<256){

$k.=$key;

Page 262: untuk memenuhi sebagian persyaratan mencapai derajat

243

}

$k=substr($k,0,256);

for ($i=0;$i<256;$i++){

$this->arc4 .= chr($i);

}

$j=0;

for ($i=0;$i<256;$i++){

$t = $this->arc4[$i];

$j = ($j + ord($t) + ord($k[$i]))%256;

$this->arc4[$i]=$this->arc4[$j];

$this->arc4[$j]=$t;

}

}

/**

* ARC4 encrypt a text string

*/

function ARC4($text){

$len=strlen($text);

$a=0;

$b=0;

$c = $this->arc4;

$out='';

for ($i=0;$i<$len;$i++){

$a = ($a+1)%256;

$t= $c[$a];

$b = ($b+ord($t))%256;

$c[$a]=$c[$b];

$c[$b]=$t;

$k = ord($c[(ord($c[$a])+ord($c[$b]))%256]);

$out.=chr(ord($text[$i]) ^ $k);

Page 263: untuk memenuhi sebagian persyaratan mencapai derajat

244

}

return $out;

}

/**

* functions which can be called to adjust or add to the document

*/

/**

* add a link in the document to an external URL

*/

function addLink($url,$x0,$y0,$x1,$y1){

$this->numObj++;

$info =

array('type'=>'link','url'=>$url,'rect'=>array($x0,$y0,$x1,$y1));

$this->o_annotation($this->numObj,'new',$info);

}

/**

* add a link in the document to an internal destination (ie. within the

document)

*/

function addInternalLink($label,$x0,$y0,$x1,$y1){

$this->numObj++;

$info =

array('type'=>'ilink','label'=>$label,'rect'=>array($x0,$y0,$x1,$y1));

$this->o_annotation($this->numObj,'new',$info);

}

/**

Page 264: untuk memenuhi sebagian persyaratan mencapai derajat

245

* set the encryption of the document

* can be used to turn it on and/or set the passwords which it will have.

* also the functions that the user will have are set here, such as print,

modify, add

*/

function setEncryption($userPass='',$ownerPass='',$pc=array()){

$p=bindec(11000000);

$options = array(

'print'=>4

,'modify'=>8

,'copy'=>16

,'add'=>32

);

foreach($pc as $k=>$v){

if ($v && isset($options[$k])){

$p+=$options[$k];

} else if (isset($options[$v])){

$p+=$options[$v];

}

}

// implement encryption on the document

if ($this->arc4_objnum == 0){

// then the block does not exist already, add it.

$this->numObj++;

if (strlen($ownerPass)==0){

$ownerPass=$userPass;

}

$this->o_encryption($this-

>numObj,'new',array('user'=>$userPass,'owner'=>$ownerPass,'p'=>$p))

;

Page 265: untuk memenuhi sebagian persyaratan mencapai derajat

246

}

}

/**

* should be used for internal checks, not implemented as yet

*/

function checkAllHere(){

}

/**

* return the pdf stream as a string returned from the function

*/

function output($debug=0){

if ($debug){

// turn compression off

$this->options['compression']=0;

}

if ($this->arc4_objnum){

$this->ARC4_init($this->encryptionKey);

}

$this->checkAllHere();

$xref=array();

$content="%PDF-1.3\n%âãÏÓ\n";

// $content="%PDF-1.3\n";

$pos=strlen($content);

foreach($this->objects as $k=>$v){

$tmp='o_'.$v['t'];

Page 266: untuk memenuhi sebagian persyaratan mencapai derajat

247

$cont=$this->$tmp($k,'out');

$content.=$cont;

$xref[]=$pos;

$pos+=strlen($cont);

}

$content.="\nxref\n0 ".(count($xref)+1)."\n0000000000 65535 f \n";

foreach($xref as $p){

$content.=substr('0000000000',0,10-strlen($p)).$p." 00000 n \n";

}

$content.="\ntrailer\n << /Size ".(count($xref)+1)."\n /Root 1 0 R\n

/Info ".$this->infoObject." 0 R\n";

// if encryption has been applied to this document then add the marker

for this dictionary

if ($this->arc4_objnum > 0){

$content .= "/Encrypt ".$this->arc4_objnum." 0 R\n";

}

if (strlen($this->fileIdentifier)){

$content .= "/ID[<".$this->fileIdentifier."><".$this-

>fileIdentifier.">]\n";

}

$content .= " >>\nstartxref\n".$pos."\n%%EOF\n";

return $content;

}

/**

* intialize a new document

* if this is called on an existing document results may be unpredictable,

but the existing document would be lost at minimum

* this function is called automatically by the constructor function

*

* @access private

Page 267: untuk memenuhi sebagian persyaratan mencapai derajat

248

*/

function newDocument($pageSize=array(0,0,612,792)){

$this->numObj=0;

$this->objects = array();

$this->numObj++;

$this->o_catalog($this->numObj,'new');

$this->numObj++;

$this->o_outlines($this->numObj,'new');

$this->numObj++;

$this->o_pages($this->numObj,'new');

$this->o_pages($this->numObj,'mediaBox',$pageSize);

$this->currentNode = 3;

$this->numObj++;

$this->o_procset($this->numObj,'new');

$this->numObj++;

$this->o_info($this->numObj,'new');

$this->numObj++;

$this->o_page($this->numObj,'new');

// need to store the first page id as there is no way to get it to the user

during

// startup

$this->firstPageId = $this->currentContents;

}

Page 268: untuk memenuhi sebagian persyaratan mencapai derajat

249

/**

* open the font file and return a php structure containing it.

* first check if this one has been done before and saved in a form more

suited to php

* note that if a php serialized version does not exist it will try and make

one, but will

* require write access to the directory to do it... it is MUCH faster to

have these serialized

* files.

*

* @access private

*/

function openFont($font){

// assume that $font contains both the path and perhaps the extension

to the file, split them

$pos=strrpos($font,'/');

if ($pos===false){

$dir = './';

$name = $font;

} else {

$dir=substr($font,0,$pos+1);

$name=substr($font,$pos+1);

}

if (substr($name,-4)=='.afm'){

$name=substr($name,0,strlen($name)-4);

}

$this->addMessage('openFont: '.$font.' - '.$name);

if (file_exists($dir.'php_'.$name.'.afm')){

Page 269: untuk memenuhi sebagian persyaratan mencapai derajat

250

$this->addMessage('openFont: php file exists

'.$dir.'php_'.$name.'.afm');

$tmp = file($dir.'php_'.$name.'.afm');

$this->fonts[$font]=unserialize($tmp[0]);

if (!isset($this->fonts[$font]['_version_']) || $this-

>fonts[$font]['_version_']<1){

// if the font file is old, then clear it out and prepare for re-creation

$this->addMessage('openFont: clear out, make way for new

version.');

unset($this->fonts[$font]);

}

}

if (!isset($this->fonts[$font]) && file_exists($dir.$name.'.afm')){

// then rebuild the php_<font>.afm file from the <font>.afm file

$this->addMessage('openFont: build php file from

'.$dir.$name.'.afm');

$data = array();

$file = file($dir.$name.'.afm');

foreach ($file as $rowA){

$row=trim($rowA);

$pos=strpos($row,' ');

if ($pos){

// then there must be some keyword

$key = substr($row,0,$pos);

switch ($key){

case 'FontName':

case 'FullName':

case 'FamilyName':

case 'Weight':

case 'ItalicAngle':

case 'IsFixedPitch':

Page 270: untuk memenuhi sebagian persyaratan mencapai derajat

251

case 'CharacterSet':

case 'UnderlinePosition':

case 'UnderlineThickness':

case 'Version':

case 'EncodingScheme':

case 'CapHeight':

case 'XHeight':

case 'Ascender':

case 'Descender':

case 'StdHW':

case 'StdVW':

case 'StartCharMetrics':

$data[$key]=trim(substr($row,$pos));

break;

case 'FontBBox':

$data[$key]=explode(' ',trim(substr($row,$pos)));

break;

case 'C':

//C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;

$bits=explode(';',trim($row));

$dtmp=array();

foreach($bits as $bit){

$bits2 = explode(' ',trim($bit));

if (strlen($bits2[0])){

if (count($bits2)>2){

$dtmp[$bits2[0]]=array();

for ($i=1;$i<count($bits2);$i++){

$dtmp[$bits2[0]][]=$bits2[$i];

}

} else if (count($bits2)==2){

$dtmp[$bits2[0]]=$bits2[1];

Page 271: untuk memenuhi sebagian persyaratan mencapai derajat

252

}

}

}

if ($dtmp['C']>=0){

$data['C'][$dtmp['C']]=$dtmp;

$data['C'][$dtmp['N']]=$dtmp;

} else {

$data['C'][$dtmp['N']]=$dtmp;

}

break;

case 'KPX':

//KPX Adieresis yacute -40

$bits=explode(' ',trim($row));

$data['KPX'][$bits[1]][$bits[2]]=$bits[3];

break;

}

}

}

$data['_version_']=1;

$this->fonts[$font]=$data;

$fp = fopen($dir.'php_'.$name.'.afm','w');

fwrite($fp,serialize($data));

fclose($fp);

} else if (!isset($this->fonts[$font])){

$this->addMessage('openFont: no font file found');

// echo 'Font not Found '.$font;

}

}

/**

* if the font is not loaded then load it and make the required object

Page 272: untuk memenuhi sebagian persyaratan mencapai derajat

253

* else just make it the current font

* the encoding array can contain 'encoding'=>

'none','WinAnsiEncoding','MacRomanEncoding' or

'MacExpertEncoding'

* note that encoding='none' will need to be used for symbolic fonts

* and 'differences' => an array of mappings between numbers 0->255

and character names.

*

*/

function selectFont($fontName,$encoding='',$set=1){

if (!isset($this->fonts[$fontName])){

// load the file

$this->openFont($fontName);

if (isset($this->fonts[$fontName])){

$this->numObj++;

$this->numFonts++;

$pos=strrpos($fontName,'/');

// $dir=substr($fontName,0,$pos+1);

$name=substr($fontName,$pos+1);

if (substr($name,-4)=='.afm'){

$name=substr($name,0,strlen($name)-4);

}

$options=array('name'=>$name);

if (is_array($encoding)){

// then encoding and differences might be set

if (isset($encoding['encoding'])){

$options['encoding']=$encoding['encoding'];

}

if (isset($encoding['differences'])){

$options['differences']=$encoding['differences'];

}

Page 273: untuk memenuhi sebagian persyaratan mencapai derajat

254

} else if (strlen($encoding)){

// then perhaps only the encoding has been set

$options['encoding']=$encoding;

}

$fontObj = $this->numObj;

$this->o_font($this->numObj,'new',$options);

$this->fonts[$fontName]['fontNum']=$this->numFonts;

// if this is a '.afm' font, and there is a '.pfa' file to go with it ( as

there

// should be for all non-basic fonts), then load it into an object and

put the

// references into the font object

$basefile = substr($fontName,0,strlen($fontName)-4);

if (file_exists($basefile.'.pfb')){

$fbtype = 'pfb';

} else if (file_exists($basefile.'.ttf')){

$fbtype = 'ttf';

} else {

$fbtype='';

}

$fbfile = $basefile.'.'.$fbtype;

// $pfbfile = substr($fontName,0,strlen($fontName)-4).'.pfb';

// $ttffile = substr($fontName,0,strlen($fontName)-4).'.ttf';

$this->addMessage('selectFont: checking for - '.$fbfile);

if (substr($fontName,-4)=='.afm' && strlen($fbtype) ){

$adobeFontName = $this->fonts[$fontName]['FontName'];

// $fontObj = $this->numObj;

$this->addMessage('selectFont: adding font file - '.$fbfile.' -

'.$adobeFontName);

// find the array of fond widths, and put that into an object.

Page 274: untuk memenuhi sebagian persyaratan mencapai derajat

255

$firstChar = -1;

$lastChar = 0;

$widths = array();

foreach ($this->fonts[$fontName]['C'] as $num=>$d){

if (intval($num)>0 || $num=='0'){

if ($lastChar>0 && $num>$lastChar+1){

for($i=$lastChar+1;$i<$num;$i++){

$widths[] = 0;

}

}

$widths[] = $d['WX'];

if ($firstChar==-1){

$firstChar = $num;

}

$lastChar = $num;

}

}

// also need to adjust the widths for the differences array

if (isset($options['differences'])){

foreach($options['differences'] as $charNum=>$charName){

if ($charNum>$lastChar){

for($i=$lastChar+1;$i<=$charNum;$i++){

$widths[]=0;

}

$lastChar=$charNum;

}

if (isset($this->fonts[$fontName]['C'][$charName])){

$widths[$charNum-$firstChar]=$this-

>fonts[$fontName]['C'][$charName]['WX'];

}

}

Page 275: untuk memenuhi sebagian persyaratan mencapai derajat

256

}

$this->addMessage('selectFont: FirstChar='.$firstChar);

$this->addMessage('selectFont: LastChar='.$lastChar);

$this->numObj++;

$this->o_contents($this->numObj,'new','raw');

$this->objects[$this->numObj]['c'].='[';

foreach($widths as $width){

$this->objects[$this->numObj]['c'].=' '.$width;

}

$this->objects[$this->numObj]['c'].=' ]';

$widthid = $this->numObj;

// load the pfb file, and put that into an object too.

// note that pdf supports only binary format type 1 font files,

though there is a

// simple utility to convert them from pfa to pfb.

$fp = fopen($fbfile,'rb');

$tmp = get_magic_quotes_runtime();

set_magic_quotes_runtime(0);

$data = fread($fp,filesize($fbfile));

set_magic_quotes_runtime($tmp);

fclose($fp);

// create the font descriptor

$this->numObj++;

$fontDescriptorId = $this->numObj;

$this->numObj++;

$pfbid = $this->numObj;

// determine flags (more than a little flakey, hopefully will not

matter much)

$flags=0;

Page 276: untuk memenuhi sebagian persyaratan mencapai derajat

257

if ($this->fonts[$fontName]['ItalicAngle']!=0){ $flags+=pow(2,6);

}

if ($this->fonts[$fontName]['IsFixedPitch']=='true'){ $flags+=1; }

$flags+=pow(2,5); // assume non-sybolic

$list =

array('Ascent'=>'Ascender','CapHeight'=>'CapHeight','Descent'=>'Desc

ender','FontBBox'=>'FontBBox','ItalicAngle'=>'ItalicAngle');

$fdopt = array(

'Flags'=>$flags

,'FontName'=>$adobeFontName

,'StemV'=>100 // don't know what the value for this should be!

);

foreach($list as $k=>$v){

if (isset($this->fonts[$fontName][$v])){

$fdopt[$k]=$this->fonts[$fontName][$v];

}

}

if ($fbtype=='pfb'){

$fdopt['FontFile']=$pfbid;

} else if ($fbtype=='ttf'){

$fdopt['FontFile2']=$pfbid;

}

$this->o_fontDescriptor($fontDescriptorId,'new',$fdopt);

// embed the font program

$this->o_contents($this->numObj,'new');

$this->objects[$pfbid]['c'].=$data;

// determine the cruicial lengths within this file

if ($fbtype=='pfb'){

Page 277: untuk memenuhi sebagian persyaratan mencapai derajat

258

$l1 = strpos($data,'eexec')+6;

$l2 = strpos($data,'00000000')-$l1;

$l3 = strlen($data)-$l2-$l1;

$this->o_contents($this-

>numObj,'add',array('Length1'=>$l1,'Length2'=>$l2,'Length3'=>$l3));

} else if ($fbtype=='ttf'){

$l1 = strlen($data);

$this->o_contents($this->numObj,'add',array('Length1'=>$l1));

}

// tell the font object about all this new stuff

$tmp = array('BaseFont'=>$adobeFontName,'Widths'=>$widthid

,'FirstChar'=>$firstChar,'LastChar'=>$lastChar

,'FontDescriptor'=>$fontDescriptorId);

if ($fbtype=='ttf'){

$tmp['SubType']='TrueType';

}

$this->addMessage('adding extra info to font.('.$fontObj.')');

foreach($tmp as $fk=>$fv){

$this->addMessage($fk." : ".$fv);

}

$this->o_font($fontObj,'add',$tmp);

} else {

$this->addMessage('selectFont: pfb or ttf file not found, ok if this

is one of the 14 standard fonts');

}

Page 278: untuk memenuhi sebagian persyaratan mencapai derajat

259

// also set the differences here, note that this means that these will

take effect only the

//first time that a font is selected, else they are ignored

if (isset($options['differences'])){

$this->fonts[$fontName]['differences']=$options['differences'];

}

}

}

if ($set && isset($this->fonts[$fontName])){

// so if for some reason the font was not set in the last one then it will

not be selected

$this->currentBaseFont=$fontName;

// the next line means that if a new font is selected, then the current

text state will be

// applied to it as well.

$this->setCurrentFont();

}

return $this->currentFontNum;

}

/**

* sets up the current font, based on the font families, and the current

text state

* note that this system is quite flexible, a <b><i> font can be

completely different to a

* <i><b> font, and even <b><b> will have to be defined within the

family to have meaning

* This function is to be called whenever the currentTextState is

changed, it will update

* the currentFont setting to whatever the appropriatte family one is.

Page 279: untuk memenuhi sebagian persyaratan mencapai derajat

260

* If the user calls selectFont themselves then that will reset the

currentBaseFont, and the currentFont

* This function will change the currentFont to whatever it should be,

but will not change the

* currentBaseFont.

*

* @access private

*/

function setCurrentFont(){

if (strlen($this->currentBaseFont)==0){

// then assume an initial font

$this->selectFont('./fonts/Helvetica.afm');

}

$cf = substr($this->currentBaseFont,strrpos($this-

>currentBaseFont,'/')+1);

if (strlen($this->currentTextState)

&& isset($this->fontFamilies[$cf])

&& isset($this->fontFamilies[$cf][$this->currentTextState])){

// then we are in some state or another

// and this font has a family, and the current setting exists within it

// select the font, then return it

$nf = substr($this->currentBaseFont,0,strrpos($this-

>currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this-

>currentTextState];

$this->selectFont($nf,'',0);

$this->currentFont = $nf;

$this->currentFontNum = $this->fonts[$nf]['fontNum'];

} else {

// the this font must not have the right family member for the current

state

// simply assume the base font

Page 280: untuk memenuhi sebagian persyaratan mencapai derajat

261

$this->currentFont = $this->currentBaseFont;

$this->currentFontNum = $this->fonts[$this-

>currentFont]['fontNum'];

}

}

/**

* function for the user to find out what the ID is of the first page that

was created during

* startup - useful if they wish to add something to it later.

*/

function getFirstPageId(){

return $this->firstPageId;

}

/**

* add content to the currently active object

*

* @access private

*/

function addContent($content){

$this->objects[$this->currentContents]['c'].=$content;

}

/**

* sets the colour for fill operations

*/

function setColor($r,$g,$b,$force=0){

if ($r>=0 && ($force || $r!=$this->currentColour['r'] || $g!=$this-

>currentColour['g'] || $b!=$this->currentColour['b'])){

Page 281: untuk memenuhi sebagian persyaratan mencapai derajat

262

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$r).'

'.sprintf('%.3f',$g).' '.sprintf('%.3f',$b).' rg';

$this->currentColour=array('r'=>$r,'g'=>$g,'b'=>$b);

}

}

/**

* sets the colour for stroke operations

*/

function setStrokeColor($r,$g,$b,$force=0){

if ($r>=0 && ($force || $r!=$this->currentStrokeColour['r'] ||

$g!=$this->currentStrokeColour['g'] || $b!=$this-

>currentStrokeColour['b'])){

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$r).'

'.sprintf('%.3f',$g).' '.sprintf('%.3f',$b).' RG';

$this->currentStrokeColour=array('r'=>$r,'g'=>$g,'b'=>$b);

}

}

/**

* draw a line from one set of coordinates to another

*/

function line($x1,$y1,$x2,$y2){

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).'

'.sprintf('%.3f',$y1).' m '.sprintf('%.3f',$x2).' '.sprintf('%.3f',$y2).' l S';

}

/**

* draw a bezier curve based on 4 control points

*/

function curve($x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3){

Page 282: untuk memenuhi sebagian persyaratan mencapai derajat

263

// in the current line style, draw a bezier curve from (x0,y0) to (x3,y3)

using the other two points

// as the control points for the curve.

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x0).'

'.sprintf('%.3f',$y0).' m '.sprintf('%.3f',$x1).' '.sprintf('%.3f',$y1);

$this->objects[$this->currentContents]['c'].= ' '.sprintf('%.3f',$x2).'

'.sprintf('%.3f',$y2).' '.sprintf('%.3f',$x3).' '.sprintf('%.3f',$y3).' c S';

}

/**

* draw a part of an ellipse

*/

function

partEllipse($x0,$y0,$astart,$afinish,$r1,$r2=0,$angle=0,$nSeg=8){

$this->ellipse($x0,$y0,$r1,$r2,$angle,$nSeg,$astart,$afinish,0);

}

/**

* draw a filled ellipse

*/

function

filledEllipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=

360){

return $this-

>ellipse($x0,$y0,$r1,$r2=0,$angle,$nSeg,$astart,$afinish,1,1);

}

/**

* draw an ellipse

* note that the part and filled ellipse are just special cases of this

function

Page 283: untuk memenuhi sebagian persyaratan mencapai derajat

264

*

* draws an ellipse in the current line style

* centered at $x0,$y0, radii $r1,$r2

* if $r2 is not set, then a circle is drawn

* nSeg is not allowed to be less than 2, as this will simply draw a line

(and will even draw a

* pretty crappy shape at 2, as we are approximating with bezier curves.

*/

function

ellipse($x0,$y0,$r1,$r2=0,$angle=0,$nSeg=8,$astart=0,$afinish=360,$c

lose=1,$fill=0){

if ($r1==0){

return;

}

if ($r2==0){

$r2=$r1;

}

if ($nSeg<2){

$nSeg=2;

}

$astart = deg2rad((float)$astart);

$afinish = deg2rad((float)$afinish);

$totalAngle =$afinish-$astart;

$dt = $totalAngle/$nSeg;

$dtm = $dt/3;

if ($angle != 0){

$a = -1*deg2rad((float)$angle);

$tmp = "\n q ";

Page 284: untuk memenuhi sebagian persyaratan mencapai derajat

265

$tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).'

'.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';

$tmp .= sprintf('%.3f',$x0).' '.sprintf('%.3f',$y0).' cm';

$this->objects[$this->currentContents]['c'].= $tmp;

$x0=0;

$y0=0;

}

$t1 = $astart;

$a0 = $x0+$r1*cos($t1);

$b0 = $y0+$r2*sin($t1);

$c0 = -$r1*sin($t1);

$d0 = $r2*cos($t1);

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$a0).'

'.sprintf('%.3f',$b0).' m ';

for ($i=1;$i<=$nSeg;$i++){

// draw this bit of the total curve

$t1 = $i*$dt+$astart;

$a1 = $x0+$r1*cos($t1);

$b1 = $y0+$r2*sin($t1);

$c1 = -$r1*sin($t1);

$d1 = $r2*cos($t1);

$this->objects[$this-

>currentContents]['c'].="\n".sprintf('%.3f',($a0+$c0*$dtm)).'

'.sprintf('%.3f',($b0+$d0*$dtm));

$this->objects[$this->currentContents]['c'].= ' '.sprintf('%.3f',($a1-

$c1*$dtm)).' '.sprintf('%.3f',($b1-$d1*$dtm)).' '.sprintf('%.3f',$a1).'

'.sprintf('%.3f',$b1).' c';

$a0=$a1;

$b0=$b1;

Page 285: untuk memenuhi sebagian persyaratan mencapai derajat

266

$c0=$c1;

$d0=$d1;

}

if ($fill){

$this->objects[$this->currentContents]['c'].=' f';

} else {

if ($close){

$this->objects[$this->currentContents]['c'].=' s'; // small 's' signifies

closing the path as well

} else {

$this->objects[$this->currentContents]['c'].=' S';

}

}

if ($angle !=0){

$this->objects[$this->currentContents]['c'].=' Q';

}

}

/**

* this sets the line drawing style.

* width, is the thickness of the line in user units

* cap is the type of cap to put on the line, values can be

'butt','round','square'

* where the diffference between 'square' and 'butt' is that 'square'

projects a flat end past the

* end of the line.

* join can be 'miter', 'round', 'bevel'

* dash is an array which sets the dash pattern, is a series of length

values, which are the lengths of the

* on and off dashes.

* (2) represents 2 on, 2 off, 2 on , 2 off ...

Page 286: untuk memenuhi sebagian persyaratan mencapai derajat

267

* (2,1) is 2 on, 1 off, 2 on, 1 off.. etc

* phase is a modifier on the dash pattern which is used to shift the point

at which the pattern starts.

*/

function setLineStyle($width=1,$cap='',$join='',$dash='',$phase=0){

// this is quite inefficient in that it sets all the parameters whenever 1 is

changed, but will fix another day

$string = '';

if ($width>0){

$string.= $width.' w';

}

$ca = array('butt'=>0,'round'=>1,'square'=>2);

if (isset($ca[$cap])){

$string.= ' '.$ca[$cap].' J';

}

$ja = array('miter'=>0,'round'=>1,'bevel'=>2);

if (isset($ja[$join])){

$string.= ' '.$ja[$join].' j';

}

if (is_array($dash)){

$string.= ' [';

foreach ($dash as $len){

$string.=' '.$len;

}

$string.= ' ] '.$phase.' d';

}

$this->currentLineStyle = $string;

$this->objects[$this->currentContents]['c'].="\n".$string;

}

Page 287: untuk memenuhi sebagian persyaratan mencapai derajat

268

/**

* draw a polygon, the syntax for this is similar to the GD polygon

command

*/

function polygon($p,$np,$f=0){

$this->objects[$this->currentContents]['c'].="\n";

$this->objects[$this->currentContents]['c'].=sprintf('%.3f',$p[0]).'

'.sprintf('%.3f',$p[1]).' m ';

for ($i=2;$i<$np*2;$i=$i+2){

$this->objects[$this->currentContents]['c'].= sprintf('%.3f',$p[$i]).'

'.sprintf('%.3f',$p[$i+1]).' l ';

}

if ($f==1){

$this->objects[$this->currentContents]['c'].=' f';

} else {

$this->objects[$this->currentContents]['c'].=' S';

}

}

/**

* a filled rectangle, note that it is the width and height of the rectangle

which are the secondary paramaters, not

* the coordinates of the upper-right corner

*/

function filledRectangle($x1,$y1,$width,$height){

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).'

'.sprintf('%.3f',$y1).' '.sprintf('%.3f',$width).' '.sprintf('%.3f',$height).' re

f';

}

/**

Page 288: untuk memenuhi sebagian persyaratan mencapai derajat

269

* draw a rectangle, note that it is the width and height of the rectangle

which are the secondary paramaters, not

* the coordinates of the upper-right corner

*/

function rectangle($x1,$y1,$width,$height){

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$x1).'

'.sprintf('%.3f',$y1).' '.sprintf('%.3f',$width).' '.sprintf('%.3f',$height).' re

S';

}

/**

* add a new page to the document

* this also makes the new page the current active object

*/

function newPage($insert=0,$id=0,$pos='after'){

// if there is a state saved, then go up the stack closing them

// then on the new page, re-open them with the right setings

if ($this->nStateStack){

for ($i=$this->nStateStack;$i>=1;$i--){

$this->restoreState($i);

}

}

$this->numObj++;

if ($insert){

// the id from the ezPdf class is the od of the contents of the page, not

the page object itself

// query that object to find the parent

$rid = $this->objects[$id]['onPage'];

Page 289: untuk memenuhi sebagian persyaratan mencapai derajat

270

$opt= array('rid'=>$rid,'pos'=>$pos);

$this->o_page($this->numObj,'new',$opt);

} else {

$this->o_page($this->numObj,'new');

}

// if there is a stack saved, then put that onto the page

if ($this->nStateStack){

for ($i=1;$i<=$this->nStateStack;$i++){

$this->saveState($i);

}

}

// and if there has been a stroke or fill colour set, then transfer them

if ($this->currentColour['r']>=0){

$this->setColor($this->currentColour['r'],$this-

>currentColour['g'],$this->currentColour['b'],1);

}

if ($this->currentStrokeColour['r']>=0){

$this->setStrokeColor($this->currentStrokeColour['r'],$this-

>currentStrokeColour['g'],$this->currentStrokeColour['b'],1);

}

// if there is a line style set, then put this in too

if (strlen($this->currentLineStyle)){

$this->objects[$this->currentContents]['c'].="\n".$this-

>currentLineStyle;

}

// the call to the o_page object set currentContents to the present page,

so this can be returned as the page id

return $this->currentContents;

}

Page 290: untuk memenuhi sebagian persyaratan mencapai derajat

271

/**

* output the pdf code, streaming it to the browser

* the relevant headers are set so that hopefully the browser will

recognise it

*/

function stream($options=''){

// setting the options allows the adjustment of the headers

// values at the moment are:

// 'Content-Disposition'=>'filename' - sets the filename, though not too

sure how well this will

// work as in my trial the browser seems to use the filename of the

php file with .pdf on the end

// 'Accept-Ranges'=>1 or 0 - if this is not set to 1, then this header is

not included, off by default

// this header seems to have caused some problems despite tha fact

that it is supposed to solve

// them, so I am leaving it off by default.

// 'compress'=> 1 or 0 - apply content stream compression, this is on

(1) by default

if (!is_array($options)){

$options=array();

}

if ( isset($options['compress']) && $options['compress']==0){

$tmp = $this->output(1);

} else {

$tmp = $this->output();

}

header("Content-type: application/pdf");

header("Content-Length: ".strlen(ltrim($tmp)));

Page 291: untuk memenuhi sebagian persyaratan mencapai derajat

272

$fileName = (isset($options['Content-

Disposition'])?$options['Content-Disposition']:'file.pdf');

header("Content-Disposition: inline; filename=".$fileName);

if (isset($options['Accept-Ranges']) && $options['Accept-

Ranges']==1){

header("Accept-Ranges: ".strlen(ltrim($tmp)));

}

echo ltrim($tmp);

}

/**

* return the height in units of the current font in the given size

*/

function getFontHeight($size){

if (!$this->numFonts){

$this->selectFont('./fonts/Helvetica');

}

// for the current font, and the given size, what is the height of the font

in user units

$h = $this->fonts[$this->currentFont]['FontBBox'][3]-$this-

>fonts[$this->currentFont]['FontBBox'][1];

return $size*$h/1000;

}

/**

* return the font decender, this will normally return a negative number

* if you add this number to the baseline, you get the level of the bottom

of the font

* it is in the pdf user units

*/

function getFontDecender($size){

Page 292: untuk memenuhi sebagian persyaratan mencapai derajat

273

// note that this will most likely return a negative value

if (!$this->numFonts){

$this->selectFont('./fonts/Helvetica');

}

$h = $this->fonts[$this->currentFont]['FontBBox'][1];

return $size*$h/1000;

}

/**

* filter the text, this is applied to all text just before being inserted into

the pdf document

* it escapes the various things that need to be escaped, and so on

*

* @access private

*/

function filterText($text){

$text = str_replace('\\','\\\\',$text);

$text = str_replace('(','\(',$text);

$text = str_replace(')','\)',$text);

$text = str_replace('&lt;','<',$text);

$text = str_replace('&gt;','>',$text);

$text = str_replace('&#039;','\'',$text);

$text = str_replace('&quot;','"',$text);

$text = str_replace('&amp;','&',$text);

return $text;

}

/**

* given a start position and information about how text is to be laid out,

calculate where

Page 293: untuk memenuhi sebagian persyaratan mencapai derajat

274

* on the page the text will end

*

* @access private

*/

function PRVTgetTextPosition($x,$y,$angle,$size,$wa,$text){

// given this information return an array containing x and y for the end

position as elements 0 and 1

$w = $this->getTextWidth($size,$text);

// need to adjust for the number of spaces in this text

$words = explode(' ',$text);

$nspaces=count($words)-1;

$w += $wa*$nspaces;

$a = deg2rad((float)$angle);

return array(cos($a)*$w+$x,-sin($a)*$w+$y);

}

/**

* wrapper function for PRVTcheckTextDirective1

*

* @access private

*/

function PRVTcheckTextDirective(&$text,$i,&$f){

$x=0;

$y=0;

return $this->PRVTcheckTextDirective1($text,$i,$f,0,$x,$y);

}

/**

* checks if the text stream contains a control directive

* if so then makes some changes and returns the number of characters

involved in the directive

Page 294: untuk memenuhi sebagian persyaratan mencapai derajat

275

* this has been re-worked to include everything neccesary to fins the

current writing point, so that

* the location can be sent to the callback function if required

* if the directive does not require a font change, then $f should be set to

0

*

* @access private

*/

function

PRVTcheckTextDirective1(&$text,$i,&$f,$final,&$x,&$y,$size=0,$an

gle=0,$wordSpaceAdjust=0){

$directive = 0;

$j=$i;

if ($text[$j]=='<'){

$j++;

switch($text[$j]){

case '/':

$j++;

if (strlen($text) <= $j){

return $directive;

}

switch($text[$j]){

case 'b':

case 'i':

$j++;

if ($text[$j]=='>'){

$p = strrpos($this->currentTextState,$text[$j-1]);

if ($p !== false){

// then there is one to remove

$this->currentTextState = substr($this-

>currentTextState,0,$p).substr($this->currentTextState,$p+1);

Page 295: untuk memenuhi sebagian persyaratan mencapai derajat

276

}

$directive=$j-$i+1;

}

break;

case 'c':

// this this might be a callback function

$j++;

$k = strpos($text,'>',$j);

if ($k!==false && $text[$j]==':'){

// then this will be treated as a callback directive

$directive = $k-$i+1;

$f=0;

// split the remainder on colons to get the function name and

the paramater

$tmp = substr($text,$j+1,$k-$j-1);

$b1 = strpos($tmp,':');

if ($b1!==false){

$func = substr($tmp,0,$b1);

$parm = substr($tmp,$b1+1);

} else {

$func=$tmp;

$parm='';

}

if (!isset($func) || !strlen(trim($func))){

$directive=0;

} else {

// only call the function if this is the final call

if ($final){

// need to assess the text position, calculate the text width to

this point

// can use getTextWidth to find the text width I think

Page 296: untuk memenuhi sebagian persyaratan mencapai derajat

277

$tmp = $this-

>PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,substr($t

ext,0,$i));

$info =

array('x'=>$tmp[0],'y'=>$tmp[1],'angle'=>$angle,'status'=>'end','p'=>$p

arm,'nCallback'=>$this->nCallback);

$x=$tmp[0];

$y=$tmp[1];

$ret = $this->$func($info);

if (is_array($ret)){

// then the return from the callback function could set the

position, to start with, later will do font colour, and font

foreach($ret as $rk=>$rv){

switch($rk){

case 'x':

case 'y':

$$rk=$rv;

break;

}

}

}

// also remove from to the stack

// for simplicity, just take from the end, fix this another day

$this->nCallback--;

if ($this->nCallback<0){

$this->nCallBack=0;

}

}

}

}

break;

Page 297: untuk memenuhi sebagian persyaratan mencapai derajat

278

}

break;

case 'b':

case 'i':

$j++;

if ($text[$j]=='>'){

$this->currentTextState.=$text[$j-1];

$directive=$j-$i+1;

}

break;

case 'C':

$noClose=1;

case 'c':

// this this might be a callback function

$j++;

$k = strpos($text,'>',$j);

if ($k!==false && $text[$j]==':'){

// then this will be treated as a callback directive

$directive = $k-$i+1;

$f=0;

// split the remainder on colons to get the function name and the

paramater

// $bits = explode(':',substr($text,$j+1,$k-$j-1));

$tmp = substr($text,$j+1,$k-$j-1);

$b1 = strpos($tmp,':');

if ($b1!==false){

$func = substr($tmp,0,$b1);

$parm = substr($tmp,$b1+1);

} else {

$func=$tmp;

$parm='';

Page 298: untuk memenuhi sebagian persyaratan mencapai derajat

279

}

if (!isset($func) || !strlen(trim($func))){

$directive=0;

} else {

// only call the function if this is the final call, ie, the one

actually doing printing, not measurement

if ($final){

// need to assess the text position, calculate the text width to

this point

// can use getTextWidth to find the text width I think

// also add the text height and decender

$tmp = $this-

>PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,substr($t

ext,0,$i));

$info =

array('x'=>$tmp[0],'y'=>$tmp[1],'angle'=>$angle,'status'=>'start','p'=>$

parm,'f'=>$func,'height'=>$this-

>getFontHeight($size),'decender'=>$this->getFontDecender($size));

$x=$tmp[0];

$y=$tmp[1];

if (!isset($noClose) || !$noClose){

// only add to the stack if this is a small 'c', therefore is a start-

stop pair

$this->nCallback++;

$info['nCallback']=$this->nCallback;

$this->callback[$this->nCallback]=$info;

}

$ret = $this->$func($info);

if (is_array($ret)){

// then the return from the callback function could set the

position, to start with, later will do font colour, and font

Page 299: untuk memenuhi sebagian persyaratan mencapai derajat

280

foreach($ret as $rk=>$rv){

switch($rk){

case 'x':

case 'y':

$$rk=$rv;

break;

}

}

}

}

}

}

break;

}

}

return $directive;

}

/**

* add text to the document, at a specified location, size and angle on the

page

*/

function addText($x,$y,$size,$text,$angle=0,$wordSpaceAdjust=0){

if (!$this->numFonts){$this->selectFont('./fonts/Helvetica');}

// if there are any open callbacks, then they should be called, to show

the start of the line

if ($this->nCallback>0){

for ($i=$this->nCallback;$i>0;$i--){

// call each function

Page 300: untuk memenuhi sebagian persyaratan mencapai derajat

281

$info =

array('x'=>$x,'y'=>$y,'angle'=>$angle,'status'=>'sol','p'=>$this-

>callback[$i]['p'],'nCallback'=>$this-

>callback[$i]['nCallback'],'height'=>$this-

>callback[$i]['height'],'decender'=>$this->callback[$i]['decender']);

$func = $this->callback[$i]['f'];

$this->$func($info);

}

}

if ($angle==0){

$this->objects[$this->currentContents]['c'].="\n".'BT

'.sprintf('%.3f',$x).' '.sprintf('%.3f',$y).' Td';

} else {

$a = deg2rad((float)$angle);

$tmp = "\n".'BT ';

$tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).'

'.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';

$tmp .= sprintf('%.3f',$x).' '.sprintf('%.3f',$y).' Tm';

$this->objects[$this->currentContents]['c'] .= $tmp;

}

if ($wordSpaceAdjust!=0 || $wordSpaceAdjust != $this-

>wordSpaceAdjust){

$this->wordSpaceAdjust=$wordSpaceAdjust;

$this->objects[$this->currentContents]['c'].='

'.sprintf('%.3f',$wordSpaceAdjust).' Tw';

}

$len=strlen($text);

$start=0;

for ($i=0;$i<$len;$i++){

$f=1;

$directive = $this->PRVTcheckTextDirective($text,$i,$f);

Page 301: untuk memenuhi sebagian persyaratan mencapai derajat

282

if ($directive){

// then we should write what we need to

if ($i>$start){

$part = substr($text,$start,$i-$start);

$this->objects[$this->currentContents]['c'].=' /F'.$this-

>currentFontNum.' '.sprintf('%.1f',$size).' Tf ';

$this->objects[$this->currentContents]['c'].=' ('.$this-

>filterText($part).') Tj';

}

if ($f){

// then there was nothing drastic done here, restore the contents

$this->setCurrentFont();

} else {

$this->objects[$this->currentContents]['c'] .= ' ET';

$f=1;

$xp=$x;

$yp=$y;

$directive = $this-

>PRVTcheckTextDirective1($text,$i,$f,1,$xp,$yp,$size,$angle,$wordS

paceAdjust);

// restart the text object

if ($angle==0){

$this->objects[$this->currentContents]['c'].="\n".'BT

'.sprintf('%.3f',$xp).' '.sprintf('%.3f',$yp).' Td';

} else {

$a = deg2rad((float)$angle);

$tmp = "\n".'BT ';

$tmp .= sprintf('%.3f',cos($a)).' '.sprintf('%.3f',(-1.0*sin($a))).'

'.sprintf('%.3f',sin($a)).' '.sprintf('%.3f',cos($a)).' ';

$tmp .= sprintf('%.3f',$xp).' '.sprintf('%.3f',$yp).' Tm';

Page 302: untuk memenuhi sebagian persyaratan mencapai derajat

283

$this->objects[$this->currentContents]['c'] .= $tmp;

}

if ($wordSpaceAdjust!=0 || $wordSpaceAdjust != $this-

>wordSpaceAdjust){

$this->wordSpaceAdjust=$wordSpaceAdjust;

$this->objects[$this->currentContents]['c'].='

'.sprintf('%.3f',$wordSpaceAdjust).' Tw';

}

}

// and move the writing point to the next piece of text

$i=$i+$directive-1;

$start=$i+1;

}

}

if ($start<$len){

$part = substr($text,$start);

$this->objects[$this->currentContents]['c'].=' /F'.$this-

>currentFontNum.' '.sprintf('%.1f',$size).' Tf ';

$this->objects[$this->currentContents]['c'].=' ('.$this-

>filterText($part).') Tj';

}

$this->objects[$this->currentContents]['c'].=' ET';

// if there are any open callbacks, then they should be called, to show

the end of the line

if ($this->nCallback>0){

for ($i=$this->nCallback;$i>0;$i--){

// call each function

$tmp = $this-

>PRVTgetTextPosition($x,$y,$angle,$size,$wordSpaceAdjust,$text);

Page 303: untuk memenuhi sebagian persyaratan mencapai derajat

284

$info =

array('x'=>$tmp[0],'y'=>$tmp[1],'angle'=>$angle,'status'=>'eol','p'=>$th

is->callback[$i]['p'],'nCallback'=>$this-

>callback[$i]['nCallback'],'height'=>$this-

>callback[$i]['height'],'decender'=>$this->callback[$i]['decender']);

$func = $this->callback[$i]['f'];

$this->$func($info);

}

}

}

/**

* calculate how wide a given text string will be on a page, at a given

size.

* this can be called externally, but is alse used by the other class

functions

*/

function getTextWidth($size,$text){

// this function should not change any of the settings, though it will

need to

// track any directives which change during calculation, so copy them

at the start

// and put them back at the end.

$store_currentTextState = $this->currentTextState;

if (!$this->numFonts){

$this->selectFont('./fonts/Helvetica');

}

// converts a number or a float to a string so it can get the width

Page 304: untuk memenuhi sebagian persyaratan mencapai derajat

285

$text = "$text";

// hmm, this is where it all starts to get tricky - use the font information

to

// calculate the width of each character, add them up and convert to

user units

$w=0;

$len=strlen($text);

$cf = $this->currentFont;

for ($i=0;$i<$len;$i++){

$f=1;

$directive = $this->PRVTcheckTextDirective($text,$i,$f);

if ($directive){

if ($f){

$this->setCurrentFont();

$cf = $this->currentFont;

}

$i=$i+$directive-1;

} else {

$char=ord($text[$i]);

if (isset($this->fonts[$cf]['differences'][$char])){

// then this character is being replaced by another

$name = $this->fonts[$cf]['differences'][$char];

if (isset($this->fonts[$cf]['C'][$name]['WX'])){

$w+=$this->fonts[$cf]['C'][$name]['WX'];

}

} else if (isset($this->fonts[$cf]['C'][$char]['WX'])){

$w+=$this->fonts[$cf]['C'][$char]['WX'];

}

}

}

Page 305: untuk memenuhi sebagian persyaratan mencapai derajat

286

$this->currentTextState = $store_currentTextState;

$this->setCurrentFont();

return $w*$size/1000;

}

/**

* do a part of the calculation for sorting out the justification of the text

*

* @access private

*/

function

PRVTadjustWrapText($text,$actual,$width,&$x,&$adjust,$justificatio

n){

switch ($justification){

case 'left':

return;

break;

case 'right':

$x+=$width-$actual;

break;

case 'center':

case 'centre':

$x+=($width-$actual)/2;

break;

case 'full':

// count the number of words

$words = explode(' ',$text);

$nspaces=count($words)-1;

if ($nspaces>0){

Page 306: untuk memenuhi sebagian persyaratan mencapai derajat

287

$adjust = ($width-$actual)/$nspaces;

} else {

$adjust=0;

}

break;

}

}

/**

* add text to the page, but ensure that it fits within a certain width

* if it does not fit then put in as much as possible, splitting at word

boundaries

* and return the remainder.

* justification and angle can also be specified for the text

*/

function

addTextWrap($x,$y,$width,$size,$text,$justification='left',$angle=0,$te

st=0){

// this will display the text, and if it goes beyond the width $width, will

backtrack to the

// previous space or hyphen, and return the remainder of the text.

// $justification can be set to 'left','right','center','centre','full'

// need to store the initial text state, as this will change during the

width calculation

// but will need to be re-set before printing, so that the chars work out

right

$store_currentTextState = $this->currentTextState;

if (!$this->numFonts){$this->selectFont('./fonts/Helvetica');}

Page 307: untuk memenuhi sebagian persyaratan mencapai derajat

288

if ($width<=0){

// error, pretend it printed ok, otherwise risking a loop

return '';

}

$w=0;

$break=0;

$breakWidth=0;

$len=strlen($text);

$cf = $this->currentFont;

$tw = $width/$size*1000;

for ($i=0;$i<$len;$i++){

$f=1;

$directive = $this->PRVTcheckTextDirective($text,$i,$f);

if ($directive){

if ($f){

$this->setCurrentFont();

$cf = $this->currentFont;

}

$i=$i+$directive-1;

} else {

$cOrd = ord($text[$i]);

if (isset($this->fonts[$cf]['differences'][$cOrd])){

// then this character is being replaced by another

$cOrd2 = $this->fonts[$cf]['differences'][$cOrd];

} else {

$cOrd2 = $cOrd;

}

if (isset($this->fonts[$cf]['C'][$cOrd2]['WX'])){

$w+=$this->fonts[$cf]['C'][$cOrd2]['WX'];

}

Page 308: untuk memenuhi sebagian persyaratan mencapai derajat

289

if ($w>$tw){

// then we need to truncate this line

if ($break>0){

// then we have somewhere that we can split :)

if ($text[$break]==' '){

$tmp = substr($text,0,$break);

} else {

$tmp = substr($text,0,$break+1);

}

$adjust=0;

$this-

>PRVTadjustWrapText($tmp,$breakWidth,$width,$x,$adjust,$justifica

tion);

// reset the text state

$this->currentTextState = $store_currentTextState;

$this->setCurrentFont();

if (!$test){

$this->addText($x,$y,$size,$tmp,$angle,$adjust);

}

return substr($text,$break+1);

} else {

// just split before the current character

$tmp = substr($text,0,$i);

$adjust=0;

$ctmp=ord($text[$i]);

if (isset($this->fonts[$cf]['differences'][$ctmp])){

$ctmp=$this->fonts[$cf]['differences'][$ctmp];

}

$tmpw=($w-$this->fonts[$cf]['C'][$ctmp]['WX'])*$size/1000;

Page 309: untuk memenuhi sebagian persyaratan mencapai derajat

290

$this-

>PRVTadjustWrapText($tmp,$tmpw,$width,$x,$adjust,$justification);

// reset the text state

$this->currentTextState = $store_currentTextState;

$this->setCurrentFont();

if (!$test){

$this->addText($x,$y,$size,$tmp,$angle,$adjust);

}

return substr($text,$i);

}

}

if ($text[$i]=='-'){

$break=$i;

$breakWidth = $w*$size/1000;

}

if ($text[$i]==' '){

$break=$i;

$ctmp=ord($text[$i]);

if (isset($this->fonts[$cf]['differences'][$ctmp])){

$ctmp=$this->fonts[$cf]['differences'][$ctmp];

}

$breakWidth = ($w-$this-

>fonts[$cf]['C'][$ctmp]['WX'])*$size/1000;

}

}

}

// then there was no need to break this line

if ($justification=='full'){

$justification='left';

}

$adjust=0;

Page 310: untuk memenuhi sebagian persyaratan mencapai derajat

291

$tmpw=$w*$size/1000;

$this-

>PRVTadjustWrapText($text,$tmpw,$width,$x,$adjust,$justification);

// reset the text state

$this->currentTextState = $store_currentTextState;

$this->setCurrentFont();

if (!$test){

$this->addText($x,$y,$size,$text,$angle,$adjust,$angle);

}

return '';

}

/**

* this will be called at a new page to return the state to what it was on

the

* end of the previous page, before the stack was closed down

* This is to get around not being able to have open 'q' across pages

*

*/

function saveState($pageEnd=0){

if ($pageEnd){

// this will be called at a new page to return the state to what it was on

the

// end of the previous page, before the stack was closed down

// This is to get around not being able to have open 'q' across pages

$opt = $this->stateStack[$pageEnd]; // ok to use this as stack starts

numbering at 1

$this->setColor($opt['col']['r'],$opt['col']['g'],$opt['col']['b'],1);

$this->setStrokeColor($opt['str']['r'],$opt['str']['g'],$opt['str']['b'],1);

$this->objects[$this->currentContents]['c'].="\n".$opt['lin'];

// $this->currentLineStyle = $opt['lin'];

Page 311: untuk memenuhi sebagian persyaratan mencapai derajat

292

} else {

$this->nStateStack++;

$this->stateStack[$this->nStateStack]=array(

'col'=>$this->currentColour

,'str'=>$this->currentStrokeColour

,'lin'=>$this->currentLineStyle

);

}

$this->objects[$this->currentContents]['c'].="\nq";

}

/**

* restore a previously saved state

*/

function restoreState($pageEnd=0){

if (!$pageEnd){

$n = $this->nStateStack;

$this->currentColour = $this->stateStack[$n]['col'];

$this->currentStrokeColour = $this->stateStack[$n]['str'];

$this->objects[$this->currentContents]['c'].="\n".$this-

>stateStack[$n]['lin'];

$this->currentLineStyle = $this->stateStack[$n]['lin'];

unset($this->stateStack[$n]);

$this->nStateStack--;

}

$this->objects[$this->currentContents]['c'].="\nQ";

}

/**

* make a loose object, the output will go into this object, until it is

closed, then will revert to

Page 312: untuk memenuhi sebagian persyaratan mencapai derajat

293

* the current one.

* this object will not appear until it is included within a page.

* the function will return the object number

*/

function openObject(){

$this->nStack++;

$this->stack[$this->nStack]=array('c'=>$this-

>currentContents,'p'=>$this->currentPage);

// add a new object of the content type, to hold the data flow

$this->numObj++;

$this->o_contents($this->numObj,'new');

$this->currentContents=$this->numObj;

$this->looseObjects[$this->numObj]=1;

return $this->numObj;

}

/**

* open an existing object for editing

*/

function reopenObject($id){

$this->nStack++;

$this->stack[$this->nStack]=array('c'=>$this-

>currentContents,'p'=>$this->currentPage);

$this->currentContents=$id;

// also if this object is the primary contents for a page, then set the

current page to its parent

if (isset($this->objects[$id]['onPage'])){

$this->currentPage = $this->objects[$id]['onPage'];

}

}

Page 313: untuk memenuhi sebagian persyaratan mencapai derajat

294

/**

* close an object

*/

function closeObject(){

// close the object, as long as there was one open in the first place,

which will be indicated by

// an objectId on the stack.

if ($this->nStack>0){

$this->currentContents=$this->stack[$this->nStack]['c'];

$this->currentPage=$this->stack[$this->nStack]['p'];

$this->nStack--;

// easier to probably not worry about removing the old entries, they

will be overwritten

// if there are new ones.

}

}

/**

* stop an object from appearing on pages from this point on

*/

function stopObject($id){

// if an object has been appearing on pages up to now, then stop it, this

page will

// be the last one that could contian it.

if (isset($this->addLooseObjects[$id])){

$this->addLooseObjects[$id]='';

}

}

/**

Page 314: untuk memenuhi sebagian persyaratan mencapai derajat

295

* after an object has been created, it wil only show if it has been added,

using this function.

*/

function addObject($id,$options='add'){

// add the specified object to the page

if (isset($this->looseObjects[$id]) && $this->currentContents!=$id){

// then it is a valid object, and it is not being added to itself

switch($options){

case 'all':

// then this object is to be added to this page (done in the next

block) and

// all future new pages.

$this->addLooseObjects[$id]='all';

case 'add':

if (isset($this->objects[$this->currentContents]['onPage'])){

// then the destination contents is the primary for the page

// (though this object is actually added to that page)

$this->o_page($this->objects[$this-

>currentContents]['onPage'],'content',$id);

}

break;

case 'even':

$this->addLooseObjects[$id]='even';

$pageObjectId=$this->objects[$this->currentContents]['onPage'];

if ($this->objects[$pageObjectId]['info']['pageNum']%2==0){

$this->addObject($id); // hacky huh :)

}

break;

case 'odd':

$this->addLooseObjects[$id]='odd';

$pageObjectId=$this->objects[$this->currentContents]['onPage'];

Page 315: untuk memenuhi sebagian persyaratan mencapai derajat

296

if ($this->objects[$pageObjectId]['info']['pageNum']%2==1){

$this->addObject($id); // hacky huh :)

}

break;

case 'next':

$this->addLooseObjects[$id]='all';

break;

case 'nexteven':

$this->addLooseObjects[$id]='even';

break;

case 'nextodd':

$this->addLooseObjects[$id]='odd';

break;

}

}

}

/**

* add content to the documents info object

*/

function addInfo($label,$value=0){

// this will only work if the label is one of the valid ones.

// modify this so that arrays can be passed as well.

// if $label is an array then assume that it is key=>value pairs

// else assume that they are both scalar, anything else will probably

error

if (is_array($label)){

foreach ($label as $l=>$v){

$this->o_info($this->infoObject,$l,$v);

}

} else {

Page 316: untuk memenuhi sebagian persyaratan mencapai derajat

297

$this->o_info($this->infoObject,$label,$value);

}

}

/**

* set the viewer preferences of the document, it is up to the browser to

obey these.

*/

function setPreferences($label,$value=0){

// this will only work if the label is one of the valid ones.

if (is_array($label)){

foreach ($label as $l=>$v){

$this->o_catalog($this-

>catalogId,'viewerPreferences',array($l=>$v));

}

} else {

$this->o_catalog($this-

>catalogId,'viewerPreferences',array($label=>$value));

}

}

/**

* extract an integer from a position in a byte stream

*

* @access private

*/

function PRVT_getBytes(&$data,$pos,$num){

// return the integer represented by $num bytes from $pos within $data

$ret=0;

for ($i=0;$i<$num;$i++){

$ret=$ret*256;

Page 317: untuk memenuhi sebagian persyaratan mencapai derajat

298

$ret+=ord($data[$pos+$i]);

}

return $ret;

}

/**

* add a PNG image into the document, from a file

* this should work with remote files

*/

function addPngFromFile($file,$x,$y,$w=0,$h=0){

// read in a png file, interpret it, then add to the system

$error=0;

$tmp = get_magic_quotes_runtime();

set_magic_quotes_runtime(0);

$fp = @fopen($file,'rb');

if ($fp){

$data='';

while(!feof($fp)){

$data .= fread($fp,1024);

}

fclose($fp);

} else {

$error = 1;

$errormsg = 'trouble opening file: '.$file;

}

set_magic_quotes_runtime($tmp);

if (!$error){

$header =

chr(137).chr(80).chr(78).chr(71).chr(13).chr(10).chr(26).chr(10);

if (substr($data,0,8)!=$header){

Page 318: untuk memenuhi sebagian persyaratan mencapai derajat

299

$error=1;

$errormsg = 'this file does not have a valid header';

}

}

if (!$error){

// set pointer

$p = 8;

$len = strlen($data);

// cycle through the file, identifying chunks

$haveHeader=0;

$info=array();

$idata='';

$pdata='';

while ($p<$len){

$chunkLen = $this->PRVT_getBytes($data,$p,4);

$chunkType = substr($data,$p+4,4);

// echo $chunkType.' - '.$chunkLen.'<br>';

switch($chunkType){

case 'IHDR':

// this is where all the file information comes from

$info['width']=$this->PRVT_getBytes($data,$p+8,4);

$info['height']=$this->PRVT_getBytes($data,$p+12,4);

$info['bitDepth']=ord($data[$p+16]);

$info['colorType']=ord($data[$p+17]);

$info['compressionMethod']=ord($data[$p+18]);

$info['filterMethod']=ord($data[$p+19]);

$info['interlaceMethod']=ord($data[$p+20]);

//print_r($info);

$haveHeader=1;

Page 319: untuk memenuhi sebagian persyaratan mencapai derajat

300

if ($info['compressionMethod']!=0){

$error=1;

$errormsg = 'unsupported compression method';

}

if ($info['filterMethod']!=0){

$error=1;

$errormsg = 'unsupported filter method';

}

break;

case 'PLTE':

$pdata.=substr($data,$p+8,$chunkLen);

break;

case 'IDAT':

$idata.=substr($data,$p+8,$chunkLen);

break;

case 'tRNS':

//this chunk can only occur once and it must occur after the PLTE

chunk and before IDAT chunk

//print "tRNS found, color type = ".$info['colorType']."<BR>";

$transparency = array();

if ($info['colorType'] == 3) { // indexed color, rbg

/* corresponding to entries in the plte chunk

Alpha for palette index 0: 1 byte

Alpha for palette index 1: 1 byte

...etc...

*/

// there will be one entry for each palette entry. up until the last

non-opaque entry.

// set up an array, stretching over all palette entries which will be

o (opaque) or 1 (transparent)

$transparency['type']='indexed';

Page 320: untuk memenuhi sebagian persyaratan mencapai derajat

301

$numPalette = strlen($pdata)/3;

$trans=0;

for ($i=$chunkLen;$i>=0;$i--){

if (ord($data[$p+8+$i])==0){

$trans=$i;

}

}

$transparency['data'] = $trans;

} elseif($info['colorType'] == 0) { // grayscale

/* corresponding to entries in the plte chunk

Gray: 2 bytes, range 0 .. (2^bitdepth)-1

*/

// $transparency['grayscale']=$this-

>PRVT_getBytes($data,$p+8,2); // g = grayscale

$transparency['type']='indexed';

$transparency['data'] = ord($data[$p+8+1]);

} elseif($info['colorType'] == 2) { // truecolor

/* corresponding to entries in the plte chunk

Red: 2 bytes, range 0 .. (2^bitdepth)-1

Green: 2 bytes, range 0 .. (2^bitdepth)-1

Blue: 2 bytes, range 0 .. (2^bitdepth)-1

*/

$transparency['r']=$this->PRVT_getBytes($data,$p+8,2); // r

from truecolor

$transparency['g']=$this->PRVT_getBytes($data,$p+10,2); // g

from truecolor

$transparency['b']=$this->PRVT_getBytes($data,$p+12,2); // b

from truecolor

Page 321: untuk memenuhi sebagian persyaratan mencapai derajat

302

} else {

//unsupported transparency type

}

// KS End new code

break;

default:

break;

}

$p += $chunkLen+12;

}

if(!$haveHeader){

$error = 1;

$errormsg = 'information header is missing';

}

if (isset($info['interlaceMethod']) && $info['interlaceMethod']){

$error = 1;

$errormsg = 'There appears to be no support for interlaced images in

pdf.';

}

}

if (!$error && $info['bitDepth'] > 8){

$error = 1;

$errormsg = 'only bit depth of 8 or less is supported';

}

if (!$error){

if ($info['colorType']!=2 && $info['colorType']!=0 &&

$info['colorType']!=3){

Page 322: untuk memenuhi sebagian persyaratan mencapai derajat

303

$error = 1;

$errormsg = 'transparancey alpha channel not supported,

transparency only supported for palette images.';

} else {

switch ($info['colorType']){

case 3:

$color = 'DeviceRGB';

$ncolor=1;

break;

case 2:

$color = 'DeviceRGB';

$ncolor=3;

break;

case 0:

$color = 'DeviceGray';

$ncolor=1;

break;

}

}

}

if ($error){

$this->addMessage('PNG error - ('.$file.') '.$errormsg);

return;

}

if ($w==0){

$w=$h/$info['height']*$info['width'];

}

if ($h==0){

$h=$w*$info['height']/$info['width'];

}

//print_r($info);

Page 323: untuk memenuhi sebagian persyaratan mencapai derajat

304

// so this image is ok... add it in.

$this->numImages++;

$im=$this->numImages;

$label='I'.$im;

$this->numObj++;

// $this->o_image($this-

>numObj,'new',array('label'=>$label,'data'=>$idata,'iw'=>$w,'ih'=>$h,'t

ype'=>'png','ic'=>$info['width']));

$options =

array('label'=>$label,'data'=>$idata,'bitsPerComponent'=>$info['bitDept

h'],'pdata'=>$pdata

,'iw'=>$info['width'],'ih'=>$info['height'],'type'=>'png','color'=>$color,'n

color'=>$ncolor);

if (isset($transparency)){

$options['transparency']=$transparency;

}

$this->o_image($this->numObj,'new',$options);

$this->objects[$this->currentContents]['c'].="\nq";

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$w)." 0

0 ".sprintf('%.3f',$h)." ".sprintf('%.3f',$x)." ".sprintf('%.3f',$y)." cm";

$this->objects[$this->currentContents]['c'].="\n/".$label.' Do';

$this->objects[$this->currentContents]['c'].="\nQ";

}

/**

* add a JPEG image into the document, from a file

*/

function addJpegFromFile($img,$x,$y,$w=0,$h=0){

Page 324: untuk memenuhi sebagian persyaratan mencapai derajat

305

// attempt to add a jpeg image straight from a file, using no GD

commands

// note that this function is unable to operate on a remote file.

if (!file_exists($img)){

return;

}

$tmp=getimagesize($img);

$imageWidth=$tmp[0];

$imageHeight=$tmp[1];

if (isset($tmp['channels'])){

$channels = $tmp['channels'];

} else {

$channels = 3;

}

if ($w<=0 && $h<=0){

$w=$imageWidth;

}

if ($w==0){

$w=$h/$imageHeight*$imageWidth;

}

if ($h==0){

$h=$w*$imageHeight/$imageWidth;

}

$fp=fopen($img,'rb');

$tmp = get_magic_quotes_runtime();

Page 325: untuk memenuhi sebagian persyaratan mencapai derajat

306

set_magic_quotes_runtime(0);

$data = fread($fp,filesize($img));

set_magic_quotes_runtime($tmp);

fclose($fp);

$this-

>addJpegImage_common($data,$x,$y,$w,$h,$imageWidth,$imageHeig

ht,$channels);

}

/**

* add an image into the document, from a GD object

* this function is not all that reliable, and I would probably encourage

people to use

* the file based functions

*/

function addImage(&$img,$x,$y,$w=0,$h=0,$quality=75){

// add a new image into the current location, as an external object

// add the image at $x,$y, and with width and height as defined by $w

& $h

// note that this will only work with full colour images and makes them

jpg images for display

// later versions could present lossless image formats if there is

interest.

// there seems to be some problem here in that images that have quality

set above 75 do not appear

// not too sure why this is, but in the meantime I have restricted this to

75.

Page 326: untuk memenuhi sebagian persyaratan mencapai derajat

307

if ($quality>75){

$quality=75;

}

// if the width or height are set to zero, then set the other one based on

keeping the image

// height/width ratio the same, if they are both zero, then give up :)

$imageWidth=imagesx($img);

$imageHeight=imagesy($img);

if ($w<=0 && $h<=0){

return;

}

if ($w==0){

$w=$h/$imageHeight*$imageWidth;

}

if ($h==0){

$h=$w*$imageHeight/$imageWidth;

}

// gotta get the data out of the img..

// so I write to a temp file, and then read it back.. soo ugly, my

apologies.

$tmpDir='/tmp';

$tmpName=tempnam($tmpDir,'img');

imagejpeg($img,$tmpName,$quality);

$fp=fopen($tmpName,'rb');

$tmp = get_magic_quotes_runtime();

set_magic_quotes_runtime(0);

Page 327: untuk memenuhi sebagian persyaratan mencapai derajat

308

$fp = @fopen($tmpName,'rb');

if ($fp){

$data='';

while(!feof($fp)){

$data .= fread($fp,1024);

}

fclose($fp);

} else {

$error = 1;

$errormsg = 'trouble opening file';

}

// $data = fread($fp,filesize($tmpName));

set_magic_quotes_runtime($tmp);

// fclose($fp);

unlink($tmpName);

$this-

>addJpegImage_common($data,$x,$y,$w,$h,$imageWidth,$imageHeig

ht);

}

/**

* common code used by the two JPEG adding functions

*

* @access private

*/

function

addJpegImage_common(&$data,$x,$y,$w=0,$h=0,$imageWidth,$imag

eHeight,$channels=3){

// note that this function is not to be called externally

// it is just the common code between the GD and the file options

$this->numImages++;

Page 328: untuk memenuhi sebagian persyaratan mencapai derajat

309

$im=$this->numImages;

$label='I'.$im;

$this->numObj++;

$this->o_image($this-

>numObj,'new',array('label'=>$label,'data'=>$data,'iw'=>$imageWidth,'

ih'=>$imageHeight,'channels'=>$channels));

$this->objects[$this->currentContents]['c'].="\nq";

$this->objects[$this->currentContents]['c'].="\n".sprintf('%.3f',$w)." 0

0 ".sprintf('%.3f',$h)." ".sprintf('%.3f',$x)." ".sprintf('%.3f',$y)." cm";

$this->objects[$this->currentContents]['c'].="\n/".$label.' Do';

$this->objects[$this->currentContents]['c'].="\nQ";

}

/**

* specify where the document should open when it first starts

*/

function openHere($style,$a=0,$b=0,$c=0){

// this function will open the document at a specified page, in a

specified style

// the values for style, and the required paramters are:

// 'XYZ' left, top, zoom

// 'Fit'

// 'FitH' top

// 'FitV' left

// 'FitR' left,bottom,right

// 'FitB'

// 'FitBH' top

// 'FitBV' left

$this->numObj++;

Page 329: untuk memenuhi sebagian persyaratan mencapai derajat

310

$this->o_destination($this->numObj,'new',array('page'=>$this-

>currentPage,'type'=>$style,'p1'=>$a,'p2'=>$b,'p3'=>$c));

$id = $this->catalogId;

$this->o_catalog($id,'openHere',$this->numObj);

}

/**

* create a labelled destination within the document

*/

function addDestination($label,$style,$a=0,$b=0,$c=0){

// associates the given label with the destination, it is done this way so

that a destination can be specified after

// it has been linked to

// styles are the same as the 'openHere' function

$this->numObj++;

$this->o_destination($this->numObj,'new',array('page'=>$this-

>currentPage,'type'=>$style,'p1'=>$a,'p2'=>$b,'p3'=>$c));

$id = $this->numObj;

// store the label->idf relationship, note that this means that labels can

be used only once

$this->destinations["$label"]=$id;

}

/**

* define font families, this is used to initialize the font families for the

default fonts

* and for the user to add new ones for their fonts. The default bahavious

can be overridden should

* that be desired.

*/

function setFontFamily($family,$options=''){

Page 330: untuk memenuhi sebagian persyaratan mencapai derajat

311

if (!is_array($options)){

if ($family=='init'){

// set the known family groups

// these font families will be used to enable bold and italic markers

to be included

// within text streams. html forms will be used... <b></b> <i></i>

$this->fontFamilies['Helvetica.afm']=array(

'b'=>'Helvetica-Bold.afm'

,'i'=>'Helvetica-Oblique.afm'

,'bi'=>'Helvetica-BoldOblique.afm'

,'ib'=>'Helvetica-BoldOblique.afm'

);

$this->fontFamilies['Courier.afm']=array(

'b'=>'Courier-Bold.afm'

,'i'=>'Courier-Oblique.afm'

,'bi'=>'Courier-BoldOblique.afm'

,'ib'=>'Courier-BoldOblique.afm'

);

$this->fontFamilies['Times-Roman.afm']=array(

'b'=>'Times-Bold.afm'

,'i'=>'Times-Italic.afm'

,'bi'=>'Times-BoldItalic.afm'

,'ib'=>'Times-BoldItalic.afm'

);

}

} else {

// the user is trying to set a font family

// note that this can also be used to set the base ones to something

else

if (strlen($family)){

$this->fontFamilies[$family] = $options;

Page 331: untuk memenuhi sebagian persyaratan mencapai derajat

312

}

}

}

/**

* used to add messages for use in debugging

*/

function addMessage($message){

$this->messages.=$message."\n";

}

/**

* a few functions which should allow the document to be treated

transactionally.

*/

function transaction($action){

switch ($action){

case 'start':

// store all the data away into the checkpoint variable

$data = get_object_vars($this);

$this->checkpoint = $data;

unset($data);

break;

case 'commit':

if (is_array($this->checkpoint) && isset($this-

>checkpoint['checkpoint'])){

$tmp = $this->checkpoint['checkpoint'];

$this->checkpoint = $tmp;

unset($tmp);

} else {

$this->checkpoint='';

Page 332: untuk memenuhi sebagian persyaratan mencapai derajat

313

}

break;

case 'rewind':

// do not destroy the current checkpoint, but move us back to the

state then, so that we can try again

if (is_array($this->checkpoint)){

// can only abort if were inside a checkpoint

$tmp = $this->checkpoint;

foreach ($tmp as $k=>$v){

if ($k != 'checkpoint'){

$this->$k=$v;

}

}

unset($tmp);

}

break;

case 'abort':

if (is_array($this->checkpoint)){

// can only abort if were inside a checkpoint

$tmp = $this->checkpoint;

foreach ($tmp as $k=>$v){

$this->$k=$v;

}

unset($tmp);

}

break;

}

}

} // end of class

?>

Page 333: untuk memenuhi sebagian persyaratan mencapai derajat

314

c. Laporan

<?php

require "../../config/koneksi.php";

include "../../config/fungsi_indotgl.php";

include "../../config/fungsi_combobox.php";

include "../../config/library.php";

echo "<h2>Cetak Laporan Hasil Diagnosa</h2><br/>

<form method=POST

action='main/main_laporan/pdf_diagnosa.php' target='_blank'>

<table>

<tr><td colspan=2><b>Laporan Per Periode</b></td></tr>

<tr><td>Dari Tanggal</td><td> : ";

combotgl(1,31,'tgl_mulai',$tgl_skrg);

combonamabln(1,12,'bln_mulai',$bln_sekarang);

combothn(2000,$thn_sekarang,'thn_mulai',$thn_sekarang);

echo "</td></tr>

<tr><td>s/d Tanggal</td><td> : ";

combotgl(1,31,'tgl_selesai',$tgl_skrg);

combonamabln(1,12,'bln_selesai',$bln_sekarang);

combothn(2000,$thn_sekarang,'thn_selesai',$thn_sekarang);

echo "</td></tr>

<tr><td colspan=2><input type=submit value=Proses></td></tr>

</table>

</form>";

?>

Page 334: untuk memenuhi sebagian persyaratan mencapai derajat

315

d. Pdf_diagnosa

<?php

include "class.ezpdf.php";

require "../../../../config/koneksi.php";

include "../../../../config/fungsi_indotgl.php";

include "../../../../config/fungsi_combobox.php";

include "../../../../config/library.php";

$pdf = new Cezpdf();

// Set margin dan font

$pdf->ezSetCmMargins(3, 3, 3, 3);

$pdf->selectFont('fonts/Courier.afm');

$all = $pdf->openObject();

// Tampilkan logo

$pdf->setStrokeColor(0, 0, 0, 1);

//$pdf->addJpegFromFile('logo.jpg',20,800,69);

// Teks di tengah atas untuk judul header

$pdf->addText(180, 820, 18,'<b>Laporan Hasil Diagnosa</b>');

$pdf->addText(200, 800, 14,'<b>Penyakit Demam Berdarah</b>');

// Garis atas untuk header

$pdf->line(10, 795, 578, 795);

// Garis bawah untuk footer

$pdf->line(10, 50, 578, 50);

// Teks kiri bawah

$pdf->addText(30,34,8,'Dicetak tgl:' . date( 'd-m-Y, H:i:s'));

Page 335: untuk memenuhi sebagian persyaratan mencapai derajat

316

$pdf->closeObject();

// Tampilkan object di semua halaman

$pdf->addObject($all, 'all');

// Baca input tanggal yang dikirimkan user

$mulai=$_POST[thn_mulai].'-'.$_POST[bln_mulai].'-

'.$_POST[tgl_mulai];

$selesai=$_POST[thn_selesai].'-'.$_POST[bln_selesai].'-

'.$_POST[tgl_selesai];

// Query untuk merelasikan kedua tabel di filter berdasarkan tanggal

$sql = mysql_query("SELECT diagnosa.kd_penyakit as

kd_penyakit,penyakit.nm_penyakit,DATE_FORMAT(tgl_diagnosa,

'%d-%m-%Y') as tanggal,

nama,jenis_kelamin,usia,alamat

FROM diagnosa, penyakit

WHERE (diagnosa.kd_penyakit=penyakit.kd_penyakit)

AND (diagnosa.tgl_diagnosa

BETWEEN '$mulai' AND '$selesai')");

$jml = mysql_num_rows($sql);

if ($jml > 0){

$i = 1;

while($r = mysql_fetch_array($sql)){

$data[$i]=array('<b>No</b>'=>$i,

'<b>Nama</b>'=>$r[nama],

'<b>Jenis Kelamin</b>'=>$r[jenis_kelamin],

Page 336: untuk memenuhi sebagian persyaratan mencapai derajat

317

'<b>Usia</b>'=>$r[usia],

'<b>Alamat</b>'=>$r[alamat],

'<b>Penyakit</b>'=>$r[nm_penyakit],

'<b>Tgl_Diagnosa</b>'=>$r[tanggal]);

$i++;

}

$pdf->ezTable($data, '', '', '');

// Penomoran halaman

$pdf->ezStartPageNumbers(320, 15, 8);

$pdf->ezStream();

}

else{

$m=$_POST[tgl_mulai].'-'.$_POST[bln_mulai].'-

'.$_POST[thn_mulai];

$s=$_POST[tgl_selesai].'-'.$_POST[bln_selesai].'-

'.$_POST[thn_selesai];

echo "Tidak ada Laporan/Hasil Diagnosa pada Tanggal $m s/d $s";

//echo '<script language="javascript">window.location =

"javascript:history.go(-1)"</script>';

}

?>

4.4.10 Main_penyakit

a. Add_penyakit

<?php

session_start();

?>

<link href="../../../../style/style.css" rel="stylesheet" type="text/css" />

Page 337: untuk memenuhi sebagian persyaratan mencapai derajat

318

<div class="add">

<fieldset>

<legend>Tambah Daftar Penyakit</legend>

<div ></div>

<?php

include "../../../../config/inc.library.php";

include "../../../../config/koneksi.php";

$dataKode = buatKode("penyakit", "H");

$dataNama = isset($_POST['txtNama']) ? $_POST['txtNama'] : '';

$dataPencegahan = isset($_POST['txtPencegahan']) ?

$_POST['txtPencegahan'] : '';

$dataPengobatan = isset($_POST['txtPengobatan']) ?

$_POST['txtPengobatan'] : '';

$dataPopulasi = isset($_POST['txtPopulasi']) ?

$_POST['txtPopulasi'] : '';

?>

<form action="?main=simpanpenyakit" method="post"

name="form1">

<table width="100%" cellpadding="2" cellspacing="1" class="table-

list">

<tr>

<th colspan="3">TAMBAH DATA PENYAKIT </th>

</tr>

<tr>

<td width="15%"><strong>Kode</strong></td>

<td width="1%"><strong>:</strong></td>

<td width="84%"><input name="textfield" value="<?php echo

$dataKode; ?>" size="10" maxlength="4"

readonly="readonly"/></td></tr>

<tr>

<td><strong>Nama Penyakit </strong></td>

Page 338: untuk memenuhi sebagian persyaratan mencapai derajat

319

<td><strong>:</strong></td>

<td><input name="txtNama" value="<?php echo $dataNama; ?>"

size="80" maxlength="100" /></td>

</tr>

<tr>

<td><strong>Pencegahan</strong></td>

<td><strong>:</strong></td>

<td><textarea name="txtPencegahan" cols="70"

rows="3"><?php echo $dataPencegahan; ?></textarea></td>

</tr>

<tr>

<td><strong>Pengobatan </strong></td>

<td><strong>:</strong></td>

<td><textarea name="txtPengobatan" cols="70" rows="3"><?php

echo $dataPengobatan; ?></textarea></td>

</tr>

<tr>

<td><strong>Nilai Believe</strong></td>

<td><strong>:</strong></td>

<td><input name="txtPopulasi" value="<?php echo

$dataPopulasi; ?>" size="20" maxlength="20" /></td>

</tr>

<tr><td>&nbsp;</td>

<td>&nbsp;</td>

<td><input type="submit" name="btnSimpan" value=" SIMPAN

"></td>

</tr>

</table>

</form>

</fieldset>

</div>

Page 339: untuk memenuhi sebagian persyaratan mencapai derajat

320

b. Edit_penyakit

<?php

session_start();

include "../../../../config/koneksi.php";

# MENGAMBIL DATA YANG DIEDIT, SESUAI KODE YANG

DIDAPAT DARI URL

$Kode = isset($_GET['Kode']) ? $_GET['Kode'] :

$_POST['txtKode'];

$mySql = "SELECT * FROM penyakit WHERE

kd_penyakit='$Kode'";

$myQry = mysql_query($mySql, $koneksidb) or die ("Query salah :

".mysql_error());

$myData = mysql_fetch_array($myQry);

# MASUKKAN DATA DARI FORM KE VARIABEL

TEMPORARY (SEMENTARA)

$dataKode = $myData['kd_penyakit'];

$dataNama = isset($_POST['txtNama']) ? $_POST['txtNama'] :

$myData['nm_penyakit'];

$dataPencegahan = isset($_POST['txtPencegahan']) ?

$_POST['txtPencegahan'] : $myData['pencegahan'];

$dataPengobatan = isset($_POST['txtPengobatan']) ?

$_POST['txtPengobatan'] : $myData['pengobatan'];

$dataPopulasi = isset($_POST['txtPopulasi']) ?

$_POST['txtPopulasi'] : $myData['np_populasi'];

?>

<form action="?main=updatepenyakit" method="post" name="form1"

enctype="multipart/form-data">

<table class="table-list" width="100%">

Page 340: untuk memenuhi sebagian persyaratan mencapai derajat

321

<tr>

<th colspan="3">UBAH DATA PENYAKIT </th>

</tr>

<tr>

<td width="15%"><strong>Kode</strong></td>

<td width="1%"><strong>:</strong></td>

<td width="84%"><input name="textfield" value="<?php echo

$dataKode; ?>" size="8" maxlength="4" readonly="readonly"/>

<input name="txtKode" type="hidden" value="<?php echo

$dataKode; ?>" /></td></tr>

<tr>

<td><strong>Nama Penyakit </strong></td>

<td><strong>:</strong></td>

<td><input name="txtNama" type="text" value="<?php echo

$dataNama; ?>" size="80" maxlength="100" />

<input name="txtLama" type="hidden" value="<?php echo

$myData['nm_penyakit']; ?>" /></td></tr>

<tr>

<td><strong>Pencegahan</strong></td>

<td><strong>:</strong></td>

<td><textarea name="txtPencegahan" cols="60"

rows="3"><?php echo $dataPencegahan; ?></textarea></td>

</tr>

<tr>

<td><strong>Pengobatan </strong></td>

<td><strong>:</strong></td>

<td><textarea name="txtPengobatan" cols="60" rows="3"><?php

echo $dataPengobatan; ?></textarea></td>

</tr>

<tr>

<td><strong>Nilai Believe</strong></td>

Page 341: untuk memenuhi sebagian persyaratan mencapai derajat

322

<td><strong>:</strong></td>

<td><input name="txtPopulasi" value="<?php echo

$dataPopulasi; ?>" size="20" maxlength="20" /></td>

</tr>

<tr><td>&nbsp;</td>

<td>&nbsp;</td>

<td><input type="submit" name="btnSimpan" value=" SIMPAN

"></td>

</tr>

</table>

</form>

</fieldset>

</div>

c. Penyakit

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".thickbox").colorbox({width:"50%",

height:"75%"});

});

</script>

<script type="text/javascript">

$(document).ready(function(){

//Examples of how to assign the ColorBox

event to elements

$(".colorbox").colorbox({width:"50%",

height:"75%"});

});

Page 342: untuk memenuhi sebagian persyaratan mencapai derajat

323

</script>

<?php

include "../../config/koneksi.php";

if (isset($_POST['Del'])) {

if ($_POST['cex'] == NULL) {

echo "<script>window.alert('Data yang akan dihapus belum di

pilih')

javascript:history.go(-1);</script>";

} else {

$a = join(",", $_POST['cex']);

//echo $a;

//exit;

$hapus= "DELETE FROM penyakit WHERE

kd_penyakit='$a'";

$hps = mysql_query($hapus, $koneksidb) or die ("Gagal

query".mysql_error());

//echo $hps;

//exit;

print "<script>alert('Data berhasil di dihapus');

javascript:history.go(-

1);</script>";

}

}else{

echo "

<div class=judul><h2>Daftar Penyakit Gigi :</h2></div>

<br/>

<form action='' method='post'>

<div style='float:right; padding:10px; width:300px; margin-top:5px;'>

Page 343: untuk memenuhi sebagian persyaratan mencapai derajat

324

<a class='thickbox'

href='main/main_penyakit/add_penyakit.php'>Tambah Daftar

Penyakit</a>

<input type='submit' name='Del' value='Hapus' onclick='return

confirmDelete();'>

</div><br/>

<table id=o width=100%><tbody>

<tr>

<th width='1%' class=th>no</th>

<th width='10%' class=th>Kode penyakit</th>

<th width='35%' class=th>nama penyakit</th>

<th width='35%' class=th>Pencegahan</th>

<th width='35%' class=th>Pengobatan</th>

<th width='25%' class=th>Nilai Believe</th>

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'>Ubah</span></div></th>

<th width='1%' bgcolor='#8DAD9C'><div

align='center'><span class='style1'><input type='checkbox'

name='checkbox[]' class='checkall'></span></div></th>

</tr>";

$p = new Paging;

$batas = 15;

$posisi = $p->cariPosisi($batas);

$tampil=mysql_query("SELECT * FROM penyakit order by

kd_penyakit DESC LIMIT $posisi,$batas");

$i= 0;

$i = $posisi;

while ($r=mysql_fetch_array($tampil)){

if (($i % 2) > 0)

$bg = '#FFFFFF'; else

$bg = '#cccccc';

Page 344: untuk memenuhi sebagian persyaratan mencapai derajat

325

echo "<tr bgcolor=" . $bg . ">

<td class=td align=center>" . ++$i ."</td>

<td class=td>$r[kd_penyakit]</td>

<td class=td>$r[nm_penyakit]</td>

<td class=td>$r[pencegahan]</td>

<td class=td>$r[pengobatan]</td>

<td class=td>$r[np_populasi]</td> <td><div

align='center' style='background-color:none;'><a class='colorbox'

href=main/main_penyakit/edit_penyakit.php?Kode=" .

$r['kd_penyakit'] . " ><img src='../images/edit.png' border='0'

width='16' height='16' /></a></div></td>

<td><div align='center'><input type='checkbox' name='cex[]'

value='" . $r['kd_penyakit'] . "'></div></td>

</tr></tr>";

}

echo "</tbody></table></form>";

$sql_pagging = mysql_query("SELECT COUNT(*) AS jml FROM

penyakit");

$pagging = mysql_fetch_array($sql_pagging);

$jml = $pagging['jml'];

echo"

</br>

<div class='results'> <span>Jumlah Data : $jml</span><br/><br/>

";

$jmldata = mysql_num_rows(mysql_query("SELECT * from

penyakit"));

$jmlhalaman = $p->jumlahHalaman($jmldata, $batas);

Page 345: untuk memenuhi sebagian persyaratan mencapai derajat

326

$linkHalaman = $p->navHalaman($_GET['halaman'], $jmlhalaman);

echo" Halaman : $linkHalaman </div>";

}

?>

d. Proses_addpenyakit

<?php

include "../../config/koneksi.php";

# Tombol Simpan diklik

if(isset($_POST['btnSimpan'])){

# Baca Variabel Form

$txtNama = $_POST['txtNama'];

$txtPencegahan = $_POST['txtPencegahan'];

$txtPengobatan = $_POST['txtPengobatan'];

$txtPopulasi = $_POST['txtPopulasi'];

# Validasi form, jika kosong sampaikan pesan error

$pesanError = array();

if (trim($txtNama)=="") {

$pesanError[] = "Data <b>Nama Penyakit</b> tidak boleh

kosong !";

}

if (trim($txtPencegahan)=="") {

$pesanError[] = "Data <b>Pencegahan</b> tidak boleh

kosong !";

}

if (trim($txtPengobatan)=="") {

$pesanError[] = "Data <b>Pengobatan</b> tidak boleh

kosong !";

}

if (trim($txtPopulasi)=="") {

Page 346: untuk memenuhi sebagian persyaratan mencapai derajat

327

$pesanError[] = "Data <b>Populasi</b> tidak boleh kosong

!";

}

# JIKA ADA PESAN ERROR DARI VALIDASI

if (count($pesanError)>=1 ){

echo "<div class='mssgBox'>";

echo "<img src='../images/attention.png'> <br><hr>";

$noPesan=0;

foreach ($pesanError as $indeks=>$pesan_tampil) {

$noPesan++;

echo "&nbsp;&nbsp; $noPesan.

$pesan_tampil<br>";

}

echo "</div> <br>";

}

else {

# SIMPAN DATA KE DATABASE. // Jika tidak

menemukan error, simpan data ke database

// Membuat kode baru

$kodeBaru = buatKode("penyakit", "H");

$mySql = "INSERT INTO penyakit (kd_penyakit,

nm_penyakit, pencegahan, pengobatan, np_populasi)

VALUES ('$kodeBaru',

'$txtNama',

'$txtPencegahan',

'$txtPengobatan',

'$txtPopulasi')";

Page 347: untuk memenuhi sebagian persyaratan mencapai derajat

328

$myQry = mysql_query($mySql, $koneksidb) or die

("Gagal query".mysql_error());

if($myQry){

echo "<meta http-equiv='refresh' content='0;

url=?main=penyakit'>";

}

exit;

}

} // Penutup Tombol Simpan

?>

e. Proses_uppdatepenyakit

<?php

include "../../config/koneksi.php";

# Tombol Simpan diklik

if(isset($_POST['btnSimpan'])){

# Baca Variabel Form

$txtNama = $_POST['txtNama'];

$txtPencegahan = $_POST['txtPencegahan'];

$txtPengobatan = $_POST['txtPengobatan'];

$txtPopulasi = $_POST['txtPopulasi'];

# Validasi form, jika kosong sampaikan pesan error

$pesanError = array();

if (trim($txtNama)=="") {

$pesanError[] = "Data <b>Nama Penyakit</b> tidak boleh kosong

!";

}

if (trim($txtPencegahan)=="") {

$pesanError[] = "Data <b>Pencegahan</b> tidak boleh kosong !";

}

Page 348: untuk memenuhi sebagian persyaratan mencapai derajat

329

if (trim($txtPengobatan)=="") {

$pesanError[] = "Data <b>Pengobatan</b> tidak boleh kosong !";

}

if (trim($txtPopulasi)=="") {

$pesanError[] = "Data <b>Populasi</b> tidak boleh kosong !";

}

# JIKA ADA PESAN ERROR DARI VALIDASI

if (count($pesanError)>=1 ){

echo "<div class='mssgBox'>";

echo "<img src='../images/attention.png'> <br><hr>";

$noPesan=0;

foreach ($pesanError as $indeks=>$pesan_tampil) {

$noPesan++;

echo "&nbsp;&nbsp; $noPesan.

$pesan_tampil<br>";

}

echo "</div> <br>";

}

else {

# SIMPAN PERUBAHAN DATA, Jika jumlah error pesanError

tidak ada, simpan datanya

// Membaca Kode dari form

$Kode = $_POST['txtKode'];

$mySql = "UPDATE penyakit SET

nm_penyakit='$txtNama', pencegahan='$txtPencegahan',

pengobatan='$txtPengobatan', np_populasi='$txtPopulasi'

WHERE kd_penyakit ='$Kode'";

Page 349: untuk memenuhi sebagian persyaratan mencapai derajat

330

$myQry = mysql_query($mySql, $koneksidb) or die ("Gagal

query".mysql_error());

if($myQry){

echo "<meta http-equiv='refresh' content='0;

url=?main=penyakit'>";

}

exit;

}

} // Penutup Tombol Simpan

# MENGAMBIL DATA YANG DIEDIT, SESUAI KODE YANG

DIDAPAT DARI URL

$Kode = isset($_GET['Kode']) ? $_GET['Kode'] : $_POST['txtKode'];

$mySql = "SELECT * FROM penyakit WHERE

kd_penyakit='$Kode'";

$myQry = mysql_query($mySql, $koneksidb) or die ("Query salah :

".mysql_error());

$myData = mysql_fetch_array($myQry);

# MASUKKAN DATA DARI FORM KE VARIABEL TEMPORARY

(SEMENTARA)

$dataKode = $myData['kd_penyakit'];

$dataNama = isset($_POST['txtNama']) ? $_POST['txtNama'] :

$myData['nm_penyakit'];

$dataPencegahan = isset($_POST['txtPencegahan']) ?

$_POST['txtPencegahan'] : $myData['pencegahan'];

$dataPengobatan = isset($_POST['txtPengobatan']) ?

$_POST['txtPengobatan'] : $myData['pengobatan'];

$dataPopulasi = isset($_POST['txtPopulasi']) ?

$_POST['txtPopulasi'] : $myData['np_populasi'];