pillinetwork hesabınızla giriş yapın.

CakePHP ile basit bir ziyaretçi defteri - 2

Bir önceki yazımda oluşturduğumuz ziyaretçi defterine herkes yazı yazabiliyordu. Şimdi de bu ziyaretçi defterine yazı yazmak için üye girişi yapma zorunluluğu ekleyeceğiz.
Ziyaretçi defterinde yazdığımız yazıların saklanacağı bir tablo oluşturmuştuk. Şimdi de kullanıcı bilgilerinin saklanacağı bir tablo oluşturacağız. Fakat bu tabloyu oluşturmadan önce diğer tablomuzda bir değişiklik yapmamız lazım. Ziyaretçi defterinde oluşturduğumuz tablo şu şekildeydi:

1
2
3
4
5
6
7
CREATE TABLE `defter`.`posts` (
`id` INT( 8 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`created` DATETIME NOT NULL ,
`title` VARCHAR( 128 ) NOT NULL ,
`body` TEXT NOT NULL ,
`user` VARCHAR( 32 ) NOT NULL
) ENGINE = MYISAM

Buradaki user alanını user_id olarak değiştirip VARCHAR( 32 ) yerine de INT( 8 ) yazıyoruz. Değişiklik yaptıktan sonraki hali:
1
2
3
4
5
6
7
CREATE TABLE `defter`.`posts` (
`id` INT( 8 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`created` DATETIME NOT NULL ,
`title` VARCHAR( 128 ) NOT NULL ,
`body` TEXT NOT NULL ,
`user_id` INT( 8 ) NOT NULL
) ENGINE = MYISAM

Bunu yapmadan önce user bir string değere karşılık geliyordu ve ziyaretçi defterine yazı eklerken kullanıcı tarafından giriliyordu. Şimdi ise user_id oldu ve bir sayıya karşılık geliyor. Yani birazdan oluşturacağımız users tablosunda yer alan kullanıcıların id değeri.
Ali isminde bir kullanıcımız olsun. Ali'nin id'si 17 olsun ve Ali ziyaretçi defterine bir yazı eklemek için giriş yapsın. Ali, ziyaretçi defterine bir yazı yazdığında bu yazının user_id değeri 17 olur. Yazıyı ekrana yazdırırken de id'si o yazının user_id değeri olan kullanıcın adı yani name değeri veritabanından okunur. Şimdi ziyaretçi defterimizi geliştirmeye başlayalım. Ziyaretçi defterini oluşturmadıysanız buradan oluşturduktan sonra yazının geri kalan kısmını okumaya devam edin.
Oluşturduğumuz veritabanında (defter) users isminde bir tablo oluşturalım.
1
2
3
4
5
6
7
CREATE TABLE `defter`.`users` (
`id` INT( 8 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 32 ) NOT NULL ,
`password` VARCHAR( 64 ) NOT NULL ,
`email` VARCHAR( 128 ) NOT NULL ,
`created` DATETIME NOT NULL
) ENGINE = MYISAM

Model Oluşturma
Şimdi cakeyol/app/models/ dizini içine user.php ismiyle user modelimizi oluşturup içine şunları yazalım:
1
2
3
4
5
6
7
<?php
class User extends AppModel
{
var $name = 'User';
var $hasMany = 'Post';
}
?>

Burada modelimizin ismini belirttik ve hasMany ilişkilendirmesini kullandık. CakePHP'de modeller arasında bazı ilişkilendirmeler yapılmaktadır. Bunlar:

  • hasOne
  • belongsTo
  • hasMany
  • hasAndBelongsToMany (HABTM)

Bu ilişkilendirmelerle modeller arasındaki bağlantılar belirtilir. Biz user modelinin birden fazla post modeline sahip olacağını belirttik. Yani bir kullanıcının birden çok yazısı olabilir.
Diğer ilişkilendirmeleri de sonraki yazılarımda anlatacağım.

Controller Oluşturma
cakeyol/app/controllers/ dizininin içine kullanici_controller.php isminde bir dosya oluşturuyoruz. İçeriği de şöyle oluyor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
class KullaniciController extends AppController
{
var $name = 'Users';
function giris(){
$this->set('hata',false);
if (!empty($this->data)){
$kullanici = $this->User->findByUsername($this->data['User']['username']);
if (!empty($kullanici['User']['password']) && $kullanici['User']['password'] == $this->data['User']['password'])
{
$this->Session->write('User',$kullanici['User']);
$this->Session->write('Userid',$kullanici['User']['id']);
$this->flash('Sisteme giriş yaptınız.','/yazilar/ekle');
}else{
$this->set('hata',true);
}
}
}
function cikis(){
$this->Session->delete('User');
$this->flash('Sistemden çıktınız.','/yazilar/index');
}
}
?>

giris() fonksiyonunda $kullanici değişkenini oluşturuyoruz ve içeriğini veritabanından çekiyoruz. Kullanıcının sayfada girdiği $this->data dizisinden okunan password değeri veritabanından çekilen password değeriyle karşılaştırılıyor. Eğer aynıysa User isminde, kullanıcının bilgilerini içeren ve Userid isminde kullanıcı id numarasını içeren bir session oluşturuyor. Ardından yazilar/ekle sayfasına yönlendiriyor. Parolalar uyuşmuyorsa sayfaya hata isminde değeri false olan bir değişken gönderiyor.
cikis() fonksiyonunda ise oluşturduğumuz sessionu silip yazilar/index sayfasına yönlendiriyoruz.
Giriş/çıkış fonksiyonlarını yazdık. Şimdi de ziyaretçi defterine yazı yazmak isteyenleri giriş yapmaya zorlayan kısmı yapacağız. Bunun için cakeyol/app dizini içine app_controller.php dosyasını oluşturalım. Bu dosyaya yazdığımız fonksiyonları herhangi bir controller içerisindeki herhangi bir fonksiyonda kullanabiliyoruz.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
class AppController extends Controller
{
function kontrolEt(){
if (!$this->Session->check('User')){
$this->redirect('/kullanici/giris');
exit();
}
}
function kullanici_id(){
if ($this->Session->check('User')){
return $this->Session->read('Userid');
}else{
return 0;
}
}
}
?>

kontrolEt() satırını kullanıcı girişinin zorunlu olduğu yerlere ekliyoruz. Biz yazilar_controller.php dosyasındaki ekle fonksiyonunun içine koyacağız.
Burada ise kullanıcının giriş yapıp yapmadığını kontrol ediyoruz. Eğer giriş yapmadıysa kullanici/giris sayfasına yönlendiriyoruz. kullanici_id() ise o giriş yapan kullanıcının id değerini verir.
View Oluşturma
Sadece giriş sayfasının viewini oluşturmamız yeterli çıkış için view oluşturmaya gerek yok. Bunun için cakeyol/app/views dizini içine users isminde bir dizin oluşturup bu dizinin içine giris.ctp dosyasını oluşturuyoruz. Dosyanın içeriği şöyle oluyor:
1
2
3
4
5
6
7
<h2>Giriş</h2>
<?php
echo $form->create('User', array('url' =>'/kullanici/giris'));
echo $form->input('username',array('label'=>'Kullanıcı adı'));
echo $form->input('password',array('label'=>'Parola'));
echo $form->end('Giriş');
?>

Kullanıcı adı ve parola kutucuklarını oluşturduk. array('label'=>'Kullanıcı adı') parametresini kullanmamızın nedeni ise varsayılan olarak bu metin kutularının etiketleri veritabanında belirttiğimiz alan adlarıydı. Bu alan adlarını ingilizce olarak yazdığımız için bu etiketler normalde User ve Password olarak görülecektir. Bu parametreyle etiketleri değiştiriyoruz.
Yazımızın başında user değerini user_id olarak değiştirmiştik. Bunun için bazı değişiklikler yapmamız lazım.
Modeldeki değişiklik
1
2
3
4
5
6
<?php
class Post extends AppModel {
var $name='Post';
var $belongsTo='User';
}
?>

$belongsTo ilişkilendirmesiyle Post modelinin User modeline ait olduğunu belirttik. Yani her yazı bir kullanıcıya ait olması lazım. Böylece yazıların user_id değerinin mutlaka bir değerinin olması lazım.
Controllerdaki değişiklik
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class YazilarController extends AppController{
var $name='Posts';
function index(){
$this->set('user_id',$this->kullanici_id());
$this->set('tum_yazilar',$this->Post->findAll($conditions=null,
$fields=null,
$order='Post.created DESC',
$limit=null,
$page=null,
$recursive=null));
}
function ekle(){
$this->kontrolEt();
$this->set('user_id',$this->kullanici_id());
if (!empty($this->data)){
if ($this->Post->save($this->data)){
$this->flash('Yazınız Eklendi','/yazilar/index');
}
}
}
}
?>

index() fonksiyonuna eklediğimiz ilk satır ile yazilar/index sayfasına kullanici_id isminde bir değer gönderiyoruz. Eğer kullanıcı giriş yaptıysa bu değer 0'dan farklıdır, aksi takdirde 0'dır. findAll() komutunun içine yazdığımız parametreler ise veritabanından çekilecek verilerin nasıl çekileceğini belirtir.

  • $conditions : Verilerin hangi koşullarda çekileceğini belirtir. Mesela "where User.group_id=5" dediğimizde group_id'si 5 olan kullanıcıları listeler.
  • $fields : Tabloda hangi alanların çekileceğini belirtir.
  • $order : Sıralamanın neye göre yapılacağını belirtir. ASC küçükten büyüğe DESC ise büyükten küçüğe doğru sıralar.
  • $limit : Bir seferde tablodan maksimum kaç satır veri çekeceğini belirtir.
  • $page : tablodan çekilen verilerin sayfasını belirler ( 1 sayfadaki eleman sayısı $limit değeridir.)

ekle() fonksiyonunun ilk satırında ise kullanıcıyı giriş yapmaya zorluyoruz. İkinci satırda da giriş yapan kullanıcının id numarasını yazilar/ekle sayfasına gönderiyoruz.
Viewdeki değişiklik:
cakeyol/app/views/posts/index.ctp dosyasını şu şekilde değiştirelim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
if ($user_id==0){
echo $html->link('Yazı yazmak için giriş yapınız.','/kullanici/giris');
}else {
echo $html->link('Yazı Ekle','/yazilar/ekle');
echo " | ";
echo $html->link('Çıkış','/kullanici/cikis');
}
foreach($tum_yazilar as $p):
echo "<h2>".$p['Post']['title']."</h2>";
echo "yazan: <b>".$p['User']['username']." | ";
echo $p['User']['created'];
echo "</b>";
echo "<p>".$p['Post']['body']."</p>";
endforeach;
?>

$user_id değeri 0 ise kullanıcı giriş yapmamış demektir. Kullanıcı giriş yapmadığı zaman sayfanın başında "Yazı eklemek için giriş yapınız" yazan bir link olacak. Bu değer 0'dan farklıysa kullanıcı giriş yapmış demektir ve sayfanın başında "Yazı Ekle" ve "Çıkış" linkleri olacaktır. 11. satıra $p['User']['username'] yerine $p['Post']['user'] yazmıştık. Önceden $p değişkeninde sadece Post modelinin değerleri vardı. post.php dosyasına eklediğimiz $belongsTo ilişkilendirmesinden sonra, $p değerinde User modelinin bilgileri de bulunur.
Ziyaretçi defterimiz hazır. Artık giriş yaparak yazı ekleyebilirsiniz.

/* ceyranci yazdı. 20 Nisan 2009 15:10. 7 yorum var */

Yorumlar

şuan users tablosu boş olduğu için herhangi bir kullanıcı tanımlı değildir. kullanıcı eklemek için :

1
2
3
4
5
6
7
8
9
10
INSERT INTO `defter`.`users` (
`id` ,
`username` ,
`password` ,
`email` ,
`created`
)
VALUES (
NULL , 'ali', 'alininparolası', 'ali@email.com', '2009-04-20 16:26:33'
);

/* ftoptas */

burda dikkatimi çeken bir şey var

$kullanici = $this->User->findByUsername($this->data['User']['username']);

bu satırı yazmışsınız lakin User modelinizde findByUsername adında bir metot yok eksikmi yazdınız acaba ?

modelde böyle bir metod tanımlamaya gerek yok. findBy şeklinde kullanılıyor. eğer tablodaki herhangi bir alana göre arama yapacaksak bunu kullanıyoruz. detaylı bilgi için şuraya bakabilirsin.

/* ftoptas */

burada bir karisiklik söz konusu
class KullaniciController deyip de
var $name = 'Posts'; şeklindwe bir tanimlama yaptınız?
ya da ayni sekilde
class YazilarController extends AppController{
var $name='Posts'; şeklinde tanımladınız da
neden
$this->Post->... seklinde kullandınız?

Haklısın tekcorap, KullaniciController sınıfında bir yanlışlık yapmışım. "Posts" değil de "Users" olması gerekiyordu. Düzeltmeyi yaptım. Belirttiğin için sağol.

/* ftoptas */

CakePhp şu sıralar ilgi alanım arasın da. Yazılarınızı takip ediyorum. Aslında cakephp ile bir kaç örnek uygulama daha paylaşsanız çok makbule geçer. Bu arada birşey sormak istiyorum

  • hasOne
  • belongsTo
  • hasMany
  • hasAndBelongsToMany (HABTM)
    bu ilişkilendirmeler hakkında bilgi verebilirmisiniz? Birde Nette bulduğum bir görsel derste ms-dos da komutlar vererek view controller v.s gibi dosyaları oluşturuyordu. Acaba bu daha kısa bir yolmu? Bu konu hakkın da bilginiz varmı?

Teşekkürler.

CakePHP ile birkaç örnek uygulama daha yayınlayacağım. Ozaman bu ilişkilendirmelerden de bahsederim.

/* ftoptas */

üye olunpillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.

Bu yazıyı rapor et. Kural dışı içeriğe rastladığınızda editörlerimize rapor ederek müdahale edilmesini sağlayabilirsiniz. (Hangi durumlarda rapor edebilirim?)

Bu site

Nokta ve pilli ortak yapımı olan kodaman.org hep birlikte içerik üretip gelirini yazarları ile paylaştığımız kolektif bir kod yazarları blogudur. Siz de katılabilirsiniz.

pilliilan

son yorumlar

arama

pillinetwork