Zırvalama Tahtası symfony, debian, PHP5, SQL ve pek çok ayrıntı

29Jun/080

sfForm ile çalışmak

sfForm symfony framework‘ü içerisinde geliştirilen ve yeni versiyonu ile gelecek olan yeni bir
form tasarım ve otomasyon aracıdır. Kolay kullanımı ve özelliştirilebilmesi yetenekleri ile göze çarpan bu
yeni aracı biraz daha yakından tanımak için bir çalışma içeriside çıkan notlarımı aşağıda bulabilirsiniz.
sfForm sınıfı

sfForm sınıfı ArrayAccess interface’ini impletemte eden bir sınıftır böylece sınıf
içerisindeki özelliklere tıpkı bir arrayin elemanlarına erişebilir gibi kullanabiliriz. Hazırladığımız formlar eğer veri tabanı ile direk iletişim kurmayacak ise sfForm sınıfından türetilmeli aksi halde bir abstract sınıf olan sfPropelForm sınıfından türetilmelidir.

sfform ile form oluşturmak için formumuza uygun bir sınıf ismi vererek sfForm sınıfından türetmeliyiz,
örnek:

class projectNameRegister extends sfForm
{
 
}

Form nesnemiz şu anda oldukça kullanışsız bir nesnedir, kullanışlı hale getirmek için sfForm sınıfını içerisinde çağırılan configure methodunu tanımlayıp içerisinde formumuza ait input elemanlarını yerleştirmemiz gerekiyor. Bunun için ise form input alanlarını taşıyan sfWidgetFormSchema nesnesinden faydalanıyoruz, bu nesnenin ilk parametresi bir array olup içerisindeki elamanlar birer sfWidgetFormInput nesnesi taşırlar.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput();
      )
    );
 
    $this->setWidgetSchema($formWidgetSchema);
  }
}

sfWidgetFormInput nesnesi 2 adet array parametre almaktadır. ilk parametre input alanına ait seçenekler diğeri ise input etiketine eklemek istediğimiz öznitelikler,

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $this->setWidgetSchema($formWidgetSchema);
  }
}

Artık formumuzu view katmanında kullanabiliriz,

tek yapmamız gereken action içerisinde formunuza ait yeni bir instance oluşturmak ve view katmanında bu instance’ı render etmesini sağlamak bunun için sfForm nesnesine ait __toString
methodundan yardım alabileceğimiz gibi dahada özelleştirmek için her form elemanına tek tek erişerek her elemanı form içerisinde istediğimiz yerde görüntüleyebiliriz.

action:

public function executeRegister($request)
{
  $registerForm = new projectNameRegister();
  if($request->isMethod('post'))
  {
    $registerForm->bind(array(
      'username' => $request->getParameter('username')
    ));
  }
 
  $this->registerForm = $registerForm;
}

view:

<form action="<?php echo url_for('/register') ?>">
  <?php echo $registerForm; ?>
</form>

yada

1
2
3
4
 
<form action="<?php echo url_for('/register') ?>">
  <div class="field-container"><?php echo $registerForm['username']->render(); ?></div>
</form>

Formumuzun post edilmesi halinde ise formumuza ait input elemanlarının veri doğrulamasını yine form nesnemiz içerisinde gerçekleştiriyoruz. Bu işlemide tıpkı sfWidgetFormSchema nesnesi gibi bir başka nesneyi sfValidatorSchema nesnesini kullanarak gerçekleştiriyoruz.
sfValidatorSchema nesnesi bir array parametre almakta ve bu array’in elemanları formumuzun input alanlarına ait doğrulama nesnelerini taşımaktadır.

sfValidatorXXXXX nesneleri iki adet array parametre almaktadır, her validator sınıfının kendi parametreleri vardır, ancak her sınıf içerisinde required, trim ve empty_values isimli parametreler varsayılan olarak gelmektedir, ayrıca hata mesajları için
invalid ve required isimli iki hata mesajı öntanımlıdır. ilk parametre doğrulama işlemlerinin neler olduğunu tanımlarken ikinci parametre ise her doğrulama işleminin başarısızlık durumunda kullanıcıya verilecek bilgi mesajlarını içermektedir.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $validationSchema = new sfValidatorSchema(array(
      'username' => new sfValidatorString(array(
          // parametre   // değeri
          'min_lenght' => 3
        ),
        array(
          // parametre doğrulaması başarısız ise kullanıcıya verilecek mesaj
          'min_lenght' => 'your username too short, min 3 char'
        ))
    ));
 
    $this->setWidgetSchema($formWidgetSchema);
 
    $this->setValidatorSchema($validationSchema);
  }
}

Artık doğrulama niteliğini kullanmak için action içerisinde bir iki ufak değişiklik yapmamız gerekmektedir.

action:

public function executeRegister($request)
{
  $registerForm = new projectNameRegister();
  if($request->isMethod('post'))
  {
    $registerForm->bind(array(
      'username' => $request->getParameter('username')
    ));
 
    if($registerForm->isValid())
    {
      // form verileri doğru ise yapılacak işlemler.
      // eğer formumuz bir sfPropelForm nesnesi ise ->save() methodunu kullanarak
      // yeni veya güncellenmiş verileri database üzerinde saklayabiliriz.
    }
  }
 
  $this->registerForm = $registerForm;
}

Eğer formumuzu özelleştirmek istersen bunun iki adet farklı yolu bulunmaktadır,
birincisi yeni bir form formatter nesnesi hazırlama, diğeri ise form nesnesi içerisindeki elemanlara erişerek html içerisine gömmek, ilk yol daha kolay gibi dursada şu an için bazı kısıtlayıcı durumu bulunmakdatır, bunların en önemlisi form alanlarındaki doğrulama hatası durumunda doğrulama hatasını taşıyan html etiketine form-error-username gibi bir id verilemiyor oluşudur. buna rağmen bu durum sizi rahatsız etmeyebilir, o halde yeni bir formatter sınıf hazırlamak oldukça kolaydır. sfForm sınıfına ait iki adet formatter sınıf mevcuttur birincisi formlarımızı table olarak görüntülerken diğeri liste elemanları olarak görüntülemektedir ve varsayılan formatter aracı table’dır. yeni bir form formatter sınıfı hazırladıktan sonra tek yapmamız gereken formumuz içerisinde bu formatter sınıfını kullanmak istediğimizi belirtmektir.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $validationSchema = new sfValidatorSchema(array(
      'username' => new sfValidatorString(array(
          // parametre   // değeri
          'min_lenght' => 3
        ),
        array(
          // parametre doğrulaması başarısız ise kullanıcıya verilecek mesaj
          'min_lenght' => 'your username too short, min 3 char'
        ))
    ));
 
    $this->setWidgetSchema($formWidgetSchema);
 
    $this->setValidatorSchema($validationSchema);
    // hey yeni bir formatter hazırladık bunu kullan ay sfForm aracı.
    $this->getWidgetSchema()->setFormFormatterName('Register');
  }
}

Form formatter sınıfı mutlak olarak sfWidgetFormSchemaFormatter abstract sınıfından extend etmelidir. yeni hazırlanan formatter sınıfı içerisinde sfWidgetFormSchemaFormatter da bulunan öz nitelikleri değiştirmemiz yeterlidir.

class sfWidgetFormSchemaFormatterRegister extends sfWidgetFormSchemaFormatter
{
    $rowFormat       = "<div class='form-field-container'>n %label%n  %field%n %help%n %error%n %hidden_fields%</div>n",
    $errorRowFormat  = "<div class='form-error'>n%errors%</div>n",
    $helpFormat      = "<span class='form-help'>%help%</span>",
    $decodatorFormat = '';
}

sfForm label metinlerini form input alanlarını taşıyan array içerisindeki eleman isimlerinden alır, ancak kimi durumda bunu değiştirmemiz gerekir bunun için yapılacak en kısa ve kolay yok form nesnemiz içerisinde
widgetSchema nesnesine ait setLabels methodunu kullanmak olacaktır.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $validationSchema = new sfValidatorSchema(array(
      'username' => new sfValidatorString(array(
          // parametre   // değeri
          'min_lenght' => 3
        ),
        array(
          // parametre doğrulaması başarısız ise kullanıcıya verilecek mesaj
          'min_lenght' => 'your username too short, min 3 char'
        ))
    ));
 
    // username alanına ait label text değerini değiştir.
    $formWidgetSchema->setLabels(array(
      'username' => 'Choose your username'
    ));
 
    $this->setWidgetSchema($formWidgetSchema);
 
    $this->setValidatorSchema($validationSchema);
    // hey yeni bir formatter hazırladık bunu kullan ay sfForm aracı.
    $this->getWidgetSchema()->setFormFormatterName('Register');
  }
}

sfForm aracına ait edindiğim bilgileri en kısa zamanda tekrar burada bulabilirsiniz.

Tagged as: , , No Comments
25Dec/070

sfPropelForm ve form otomasyonu

symfony ile gelen sfForm nesnesinden daha önce bahsetmiştik,
şimdi ise sfPropelForm nesnesinden biraz söz edelim.

symfony 1.1 sürümü ile beraber symfony komut parametrelerine bir yenisi daha ekleniyor

$ symfony propel:build-forms

bu yeni eklenen görev sayesinde veri tabanında bulunan tablolar için formlarımızın hazırlanması sadece bir kaç saniyelik iş olup çıkıyor, yukarıdaki komutu çalıştırdığımızda aşağıdaki gibi kısa bir bilgi mesajı görüyoruz.

./symfony propel:build-form
>> propel    generating form classes

ve hemen ardından lib/ dizini altında form isimli bir dizin oluştuğunu fark ediyoruz ve dalıyoruz içerisine.

$ ls  lib/form
drwxr-xr-x 2 timu timu 4096 2007-12-25 17:32 base
-rw-r--r-- 1 timu timu  244 2007-12-25 17:32 BaseFormPropel.class.php
-rw-r--r-- 1 timu timu  239 2007-12-25 17:32 UsersForm.class.php

eğer UsersForm.class.php içerisine bakacak olursak bu sınıfın BaseUsersForm sınıfından extend edildiğini görebiliriz, bu sınıfın base/ dizini içerisinde bulunduğunu bildiğimizden içerisine bir bakalım ve neler olduğunu öğrenelim.

BaseUsersForm.class.php

<?php
 
/**
 * Users form base class.
 *
 * @package    form
 * @subpackage users
 * @version    SVN: $Id: sfPropelFormGeneratedTemplate.php 6174 2007-11-27 06:22:40Z fabien $
 */
class BaseUsersForm extends BaseFormPropel
{
  public function setup()
  {
    $this->setWidgetSchema(new sfWidgetFormSchema(array(
      'id'       => new sfWidgetFormInputHidden(),
      'username' => new sfWidgetFormInput(),
      'password' => new sfWidgetFormInput(),
      'email'    => new sfWidgetFormInput(),
    )));
 
    $this->setValidatorSchema(new sfValidatorSchema(array(
      'id'       => new sfValidatorInteger(array('required' => false)),
      'username' => new sfValidatorString(),
      'password' => new sfValidatorString(),
      'email'    => new sfValidatorString(),
    )));
 
    $this->widgetSchema->setNameFormat('users[%s]');
 
    $this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
 
    parent::setup();
  }
 
  public function getModelName()
  {
    return 'Users';
  }
 
 
 
}

Şimdi ise methodları inceleyerek neler yaptığına bir göz atalım,

setup() methodunda bulunan

$this->setWidgetSchema(new sfWidgetFormSchema(array(
      'id'       => new sfWidgetFormInputHidden(),
      'username' => new sfWidgetFormInput(),
      'password' => new sfWidgetFormInput(),
      'email'    => new sfWidgetFormInput(),
    )));

satırları ile anlıyoruz ki, schema.(x|y)ml dosyasında bulunan users tablosuna ait sütünların tamamı bu form içerisinde kullanılacak ve bu alanlara girilen bilgilerin doğrulaması aşağıdaki gibi yapılacak.

    $this->setValidatorSchema(new sfValidatorSchema(array(
      'id'       => new sfValidatorInteger(array('required' => false)),
      'username' => new sfValidatorString(),
      'password' => new sfValidatorString(),
      'email'    => new sfValidatorString(),
    )));

aşağıdaki satırdan anlıyoruzki bu form verilerini save() methodu ile kaydetmeye çalıştığımızda form içerisinde bulunan veriler Users nesnesine girilecek ve veri tabanı üzerinde insert/update işlemi gerçekleştirilicek.

  public function getModelName()
  {
    return 'Users';
  }

peki ya form verisinin otomatik olarak belirlenen doğrulama sisteminde değişiklik yapmak istersem?
BaseUsersForm.class.php dosyasının her build-form işleminde yeniden oluşturulacağını unutmayın, bu neden ile kişiselleştirilen değişiklikleri bir alt dizinde bulunan UsersForm.class.php içerisinde gerçekleştireceğiz.

Bir diğer soru ise bu değişikliği nerede gerçekleştireceğimiz, form ile ilgili nerede ise tüm bilgileri UsersForm nesnesi içerisinde bulunan configure() methodu içerisinde yapabiliriz.
Bununla ilgili örnekleri önümüzdeki günler içerisinde vereceğim, şimdi dışarı çıkıp biraz dolaşın, sevilginizin yanına gidin, ne bileyim yapın işte birşeyler.