Moduł WWW dla serwera FICS

2010-09-30 , Papiewski Łukasz , Programowanie / Kodzenie

Ten zaimplementowany moduł obsługuje podstawowe czynności na bazie danych serwera chessd (zob. chessd). Wykorzystuje strukturę narzuconą w Zend Framework (zob. zend-dir). Służy pośrednio, dzięki opracowanym skryptom (zob. chessd-scripts), do komunikacji z serwerem i jego zarządzania.

Serwer chessd jest programem napisanym w języku C wykorzystującym połączenie TCP oraz bazę danych. Każda tabela tego serwera została tu zamodelowana w postaci oddzielnej klasy PHP. Wykorzystano w tym celu dziedziczenie po klasie Zend_Db_Abstract znajdującej się w bibliotece Zend.

Opis klasy modelu użytkownika

Zmienna _name określa tabele z bazy. Klasa jest dziedziczy po Zend_Db_Table_Abstract i dzięki temu można używać takich funkcji jak:

  • find - wyszukiwanie,
  • save - zapisywanie,
  • insert - dodawania danych,
  • select - specyfikowanie rekordów,
  • fetchAll - pobierania określonych rekordów.

Określone jest tu także połączenie z bazą, będące obiektem Zend_Db w zmiennej o nazwie _db.

caption=Chessd_Model_User

W linijkach 7-13 jest inicjowany obiekt Zend_Db dla oddzielnego połączenia z bazą danych serwera chessd. Funkcja w linijce 15 ma za zadanie aktualizowanie wpisów użytkownika serwera ICS. Dane POST są uzyskiwane dzięki formularzowi wykorzystującemu klasę Zend_Form. Jeśli użytkownik został odnaleziony (17) to zwracany jest obiekt Zend_Db_Table_Row reprezentujący znaleziony wiersz tabeli. Następnie modyfikowane są zmienne tego obiektu na podstawie zweryfikowanych wcześniej danych POST (20, 22, 25, 29). Funkcja save tego obiektu zapisuje zmiany do bazy (22). W przypadku jakichkolwiek nieprzewidzianych problemów zgłaszany jest wyjątek (35).

<?php
class Chessd_Model_User extends Zend_Db_Table_Abstract
{
 
      protected $_name='ChessdUser';
 
    function _setupDatabaseAdapter() {
	$this->_db = Zend_Db::factory('Pdo_Mysql', array(
		    'host'     => 'localhost',
		    'username' => 'chessd',
		    'password' => '******',
		    'dbname'   => 'chessd'
		    ));
    }
  public function updateUser2($u)
    {
	$rowUser=$this->find($u['id'])->current();
	if($rowUser){
	    if(isset($u['username']) && !empty($u['username']))
		$rowUser->username=$u['username'];
	    if(isset($u['fullname']) && !empty($u['fullname']))
		$rowUser->fullname=$u['fullname'];
 
	    if(isset($u['emailaddress']) && !empty($u['emailaddress']))
		$rowUser->emailaddress=$u['emailaddress'];
	    else if(isset($u['email']) && !empty($u['email']))
		$rowUser->emailaddress=$u['email'];
	    if(isset($u['deleted']) && !empty($u['deleted']))
		$rowUser->deleted=$u['deleted'];
	    else
		$rowUser->deleted='0';
	    $rowUser->save();
	    return $rowUser;
	}else{
	    throw new Zend_Exception('Error');
	} 
 
    }
}

Opis klasy formularza użytkownika

Jak pokazuje (zob. chessdformuser), formularz zawiera elementy (Zend_Form_Element) określone nazwą i typem (linijki 8, 12, 16, 23, 28). Przykładowo w linijce 10 typem jest text a nazwą username. Typy wprost przekładają się na podstawowe elemety HTML formularza: pole tekstowe, wiersz, pole ukryte, lista itp. Każdy element jest konstruowany funkcją createElement a następnie dodawany do obiektu funkcją addElement. Klasa zawiera wbudowane mechanizmy ułatwiające sprawdzanie, filtrowanie i wyświetlanie. Można określić czy dane pole jest wymagane funkcją setRequired. W przypadku jakichkolwiek błędów zostaną zwrócone zdefiniowane komunikaty. Obiekt może być wyświetlony w postaci gotowego formularza przy użyciu podstawowych funkcji print lub echo (np. print new Chessd_Form_User()).

caption=Chessd_Form_User,label=chessdformuser
<?php
class Chessd_Form_User extends Zend_Form
{
 
    public function init()
    {
	$this->setmethod('post');
	$id=$this->createelement('hidden','id');
	$id->setdecorators(array('ViewHelper'));
	$this->addelement($id);
 
	$id=$this->createelement('hidden','userid');
	$id->setdecorators(array('ViewHelper'));
	$this->addelement($id);
 
	$username=$this->createelement('text','username');
	$username->setlabel('nazwa uzytkownika: ');
	$username->setrequired(true);
	$username->addfilter('StripTags');
	$username->adderrormessage('wymagana jest nazwa uzytkownika!');
	$this->addelement($username);
 
	$password=$this->createelement('password','password');
	$password->setlabel('haslo: ');
	$password->setrequired(true);
	$this->addelement($password);
 
	$email=$this->createelement('text','email');
	$email->setlabel('email :');
	$email->setrequired(false);
	$email->addfilter('StripTags');
	$email->addvalidator(new Zend_Validate_EmailAddress());
	$email->setrequired(true);
	$this->addelement($email);
 
	$fullname=$this->createelement('text','fullname');
	$fullname->setlabel('Parametry silnika :');
	$fullname->setrequired(true);
	$fullname->addfilter('striptags');
	$this->addelement($fullname);
	$this->getElement('fullname')->setRequired(true);
 
	$prompt=$this->createElement('text','prompt');
	$prompt->setLabel('Prompt');
	$this->addElement($prompt);
 
	$submit=$this->addelement('submit','submit',array('label'=>'zatwierdz'));
    }
 
    public function toPasswordForm(){
	$this->removeElement('fullname');
	$this->removeElement('emailaddress');
	$this->removeElement('username');
	$this->removeElement('prompt');
	$this->removeElement('email');
    }
 
    public function addActivetionCheckbox()
    {
	$active=$this->createElement('checkbox','activate');
	$active->setLabel('Aktywny');
	$this->addElement($active);
    }
 
 
}

Opis klasy kontrolera użytkownika

Opracowana klasa wykonuje wszystkie operacje związane z logiką użytkownika serwera chessd (przykładową komendę ukazuje (zob. updateAction)).

caption=updateAction,label=updateAction
public function updateAction()
{
    // action body
 
 
    $userForm=new Chessd_Form_User();
    $userForm->removeElement('password');
    $userModel=new Chessd_Model_User();
 
    if($this->_request->isPost()){
	if($userForm->isValid($_POST)){
 
	    $ident=Zend_Auth::getInstance()->getIdentity();
	    $userModel->updateUser2(array(
		'id'=>$userForm->getValue('id'),
		'userid'=>$ident->id,
		'username'=>$userForm->getValue('username'),
		'emailaddress'=>$userForm->getValue('email'),
		'fullname'=>$userForm->getValue('fullname'),
		));
	    return $this->_forward('mylist');
	}
    }else{
	$id=$this->_request->getParam('id');
	$currentUser=$userModel->find($id)->current();
 
	$userForm->populate($currentUser->toArray());
	$userForm->getElement('email')
	    ->setValue($currentUser->emailaddress);
	$userForm->getElement('id')
	    ->setValue($currentUser->chessduserid);
 
    }
    $userForm->setAction('/chessd/user/update');
    $this->view->form=$userForm;
}

W linijce 6 konstruowany jest nowy obiekt dziedziczący po Zend_Form. Obiekt reprezentuje formularz wraz z funkcjami i danymi z nim związanymi. Np. formularz ten posiada funkcję sprawdzającą obecność danych POST (10) oraz ich poprawność (11). Wszystkie dane z obiektu Chessd_Form_User są pobierane za pomocą metody getValue.

W linijce (7) metody updateUser kontrolera User_Controller modułu Chessd, jest zwracany obiekt Chessd_Model_User dziedziczący po Zend_Db_Table_Abstract. Klasa abstrakcyjna dostarcza funkcje do wybierania i zapisywania danych z tabeli. W linijce 14 wykorzystana jest napisana funkcja oparta o te metody i zapisująca zaktualizowany rekord w bazie.

W linijce 25 przekazywane są aktualne dane do formularza, wykorzystując do tego funkcję: toArray oraz populate. Dane, tu formularz, są przekazywane dalej do widoku, który jest zawsze identyfikowany jako zmienna view (34).

Poniżej plik renderujący dla danego widoku caption=Plik,language=html,label=updatescript

Edycja uzytkownika FICS
<?php echo $this->form; ?>
<p>
<a href='/chessd/user/password/id/<?php echo $this->form->getElement('id')->getValue();?>'>Zmien haslo</a>
</p>

Z reguły widok wyświetla dane z odpowiedniego kontrolera, tu formularz i link do następnego kontrolera.

Cytaty

- Simplicity is the ultimate sophistication. - Leonardo da Vinci,
- Popularny człowiek wzbudza zawiść potężnych - Thufir Hawat o Leto Atrydzie (na Kaladanie),
- Szczęście następuje po smutku, a smutek po szczęściu; człowiek jest naprawdę wolny, gdy przestaje rozróżniać między smutkiem a szczęściem, między dobrem a złem - Aforyzmy buddyjskie.