Con il post di oggi arricchiremo la nostra libreria con tre nuove funzionalità che ci permetteranno di:

  • aggiungere un nuovo libro all’elenco di cui già disponiamo;
  • eliminare un libro;
  • modificare il titolo di un libro o il nome del suo scrittore.

Siete pronti per iniziare?

La Form

Per poter aggiungere un nuovo libro, avremo bisogno di una form con due campi di input dove inseriremo il titolo del libro e lo scrittore ed un pulsante di conferma.

Creare una form sarà molto semplice: basterà aprire il prompt dei comandi, “spostarsi” nella cartella in cui si trova l’applicazione, che nel mio caso è

  • C:\Program Files\Zend\Apache2\htdocs\myapplication

e digitare il comando:

zf create form Book

Dopo aver “refreshato” il progetto su Eclipse, dovremmo vedere una nuova cartella, chiamata forms, con all’interno il file Book.php

Apriamo il file e modifichiamo il codice come segue, così da implementare la form descritta precedentemente:

class Application_Form_Book extends Zend_Form
{
    public function init()
    {
    	// Imposta l'id della form con il valore 'book'
        $this->setName('book');

        // Crea l'input text per inserire lo scrittore e successivamente:
        // 1 - imposta l'etichetta con il valore 'Scrittore'
        // 2 - imposta la proprietà required a 'true'
        // 3 - aggiunge un filtro per togliere gli eventuali spazi laterali
        // 4 - aggiunge un validatore che controlla che il valore sia inserito
        $scrittore = new Zend_Form_Element_Text('scrittore');
        $scrittore->setLabel('Scrittore')
               ->setRequired(true)
               ->addFilter('StringTrim')
               ->addValidator('NotEmpty');
               
        // Crea l'input text per inserire il titolo e successivamente:
        // 1 - imposta l'etichetta con il valore 'Titolo'
        // 2 - imposta la proprietà required a 'true'
        // 3 - aggiunge un filtro per togliere gli eventuali spazi laterali
        // 4 - aggiunge un validatore che controlla che il valore sia inserito
        $titolo = new Zend_Form_Element_Text('titolo');
        $titolo->setLabel('Titolo')
              ->setRequired(true)
              ->addFilter('StringTrim')
              ->addValidator('NotEmpty');

        // Crea un campo nascosto e
        // aggiunge un filtro che controlla che il valore sia un intero
        $id = new Zend_Form_Element_Hidden('id');
        $id->addFilter('Int');
        
        // Crea il pulsante per inviare i valori al server
        $submit = new Zend_Form_Element_Submit('submit');
        $submit->setAttrib('id', 'submitbutton');

        // Aggiunge tutti gli elementi sopra creati alla form
        $this->addElements(array($id, $titolo, $scrittore, $submit));
    }
}

Aggiungere un nuovo libro

Per poter aggiungere un libro dovremo, come prima cosa, modificare il Model del nostro applicativo: questo perchè dovremo gestire l’inserimento sul database di un nuovo record.

Implementiamo quindi un metodo, chiamato addBook, nel file Books.php:

    /**
     * Dato il titolo di un libro ed il suo scrittore,
     * lo inserisce in tabella
     */
    public function addBook($titolo, $scrittore)
    {
        $record = array(
            'scrittore' => $scrittore,
            'titolo' => $titolo,
        );

        $this->insert($record);
    }

Il secondo passo sarà quello di modificare la logica di business presente nel Controller: con essa gestiremo la visualizzazione della form e l’inserimento del libro nel database.

Anche in questo caso aggiungeremo un nuovo metodo chiamato addAction all’interno del file IndexController.php:

    /**
     * Il metodo si occuperà di visualizzare la form e
     * di inserire sul database un nuovo libro
     */
    public function addAction()
    {
    	// Viene creata una form
    	$form = new Application_Form_Book();
    	
    	// Imposta l'etichetta del bottone con il valore 'Aggiungi'
        $form->submit->setLabel('Aggiungi');
        
        // Imposta la vista con la form appena creata
        $this->view->form = $form;

        if ($this->getRequest()->isPost()) 
        {
            $formData = $this->getRequest()->getPost();
            
            if ($form->isValid($formData)) 
            {
            	
            	// Estrae dalla form i due valori inseriti
                $scrittore = $form->getValue('scrittore');
                $titolo = $form->getValue('titolo');
                
                // Esegue l'inserimento sul database
                $books = new Application_Model_DbTable_Books();
                $books->addBook($titolo, $scrittore);
                
                // Reindirizza alla pagina principale
                $this->_helper->redirector('index');
            } 
            else 
            {
                $form->populate($formData);
            }
        }
    }

Non ci rimane che creare la View che chiameremo add.phtml e la posizioneremo nella cartella: application -> views -> scripts -> index.

Il codice che andremo a scrivere sarà veramente pochino!! 🙂

<?php 
   echo $this->form;
?>

Come ultimo passaggio visualizziamo un link nella pagina principale (la index.phtml) così da poter navigare nella pagina appena creata:

<html> 
<head>	
</head>
<body>

<table>

	<tr>
	    <th>Autore</th>
	    <th>Libro</th>
	</tr>
	
	<?php foreach($this->books as $book) : ?>
	<tr>
		<td><?php echo $this->escape($book->scrittore);?></td>
	    <td><?php echo $this->escape($book->titolo);?></td>
	</tr>
	<?php endforeach; ?>
	
</table>

<p>
	<a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'add'));?>">Aggiungi un libro</a>
</p>

</body>
</html>

Modificare un libro

Per modificare un libro non dovremo fare altro che recuperare le informazioni del libro che si vuol modificare, mostrarle in una form uguale a quella creata precedentemente ed infine aggiornare il record sul database.

Inseriamo quindi due metodi alla classe Books.php che chiameremo getBook e editBook:

    /**
     * Dato l'identificativo di un libro lo ricerca in tabella
     */
    public function getBook($id)
    {
        $id = (int)$id;
        $row = $this->fetchRow('id = ' . $id);
       
        return $row->toArray();
    }
    /**
     * Dato l'id di un libro, ne modifico
     * il titolo ed il suo scrittore
     */
    public function editBook($id, $titolo, $scrittore)
    {
        $record = array(
            'scrittore' => $scrittore,
            'titolo' => $titolo,
        );
        
        $this->update($record, 'id = '. (int)$id);
    }

Nel file IndexController.php implementiamo un nuovo metodo, chiamato editAction, che non farà altro che mostrare i valori recuperati del libro nella form e che salverà le modifiche una volta premuto il pulsante ‘Salva’:

    /**
     * Il metodo permette di modificare il libro
     * attraverso la form e di salvarlo sul database
     */    
    public function editAction()
    {
        // Viene creata una form e viene impostata la
        // label del pulsante a 'Salva'
        $form = new Application_Form_Book();
        $form->submit->setLabel('Salva');
        $this->view->form = $form;
        
        if ($this->getRequest()->isPost()) 
        {
            $formData = $this->getRequest()->getPost();
            
            if ($form->isValid($formData)) 
            {
                // Alla pressione del pulsante 'Salva' viene eseguito
                // un update sul database per i valori inseriti nella form
                $id = (int)$form->getValue('id');
                $scrittore = $form->getValue('scrittore');
                $titolo = $form->getValue('titolo');
                $books = new Application_Model_DbTable_Books();
                $books->editBook($id, $titolo, $scrittore);
                
                // Reindirizza alla pagina principale
                $this->_helper->redirector('index');
            } 
            else 
            {
                $form->populate($formData);
            }
        } 
        else 
        {
            $id = $this->_getParam('id', 0);
            
            if ($id > 0) 
            {
                // Popola la form con i valori del libro che vogliamo modificare
                $books = new Application_Model_DbTable_Books();
                $form->populate($books->getBook($id));
            }
        }	
    }

La pagina di modifica del libro sarà uguale identica a quella di inserimento: ci basterà creare il file edit.phtml nella cartella:

  • application -> views -> scripts -> index

ed inserirci il codice sotto riportato:

<?php 
	echo $this->form ;
?>

Andiamo ancora una volta a modificare la pagina principale, aggiungendo ad ogni libro un link che permetta appunto di poterlo modificare:

<html> 
<head>	
</head>
<body>

<table>

	<tr>
	    <th>Autore</th>
	    <th>Libro</th>
	</tr>
	
	<?php foreach($this->books as $book) : ?>
	<tr>
		<td><?php echo $this->escape($book->scrittore);?></td>
	    <td><?php echo $this->escape($book->titolo);?></td>
	    <td>
        	<a href="<?php echo $this->url(array('controller'=>'index', 
            	'action'=>'edit', 'id'=>$book->id));?>">Modifica</a>
        </td>
	</tr>
	<?php endforeach; ?>
	
</table>

<p>
	<a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'add'));?>">Aggiungi un libro</a>
</p>

</body>
</html>

Eliminare un libro

Siamo arrivati all’implementazione della funzionalità di cancellazione di un libro.

Il primo passo sarà quello di aggiungere il metodo deleteBook nel file Books.php che avrà il compito di eliminare il libro dal database.

    /**
     * Dato l'id di un libro, 
     * lo cancello dalla lista
     */
    public function deleteBook($id)
    {
        $this->delete('id =' . (int)$id);
    }

Per quanto riguarda il controller, avremo bisogno di un nuovo metodo che visualizzerà la pagina di cancellazione del libro e richiamerà la funzionalità di cancellazione: aggiungiamo in indexController.php il metodo deleteAction.

    /**
     * Il metodo permette di cancellare il libro
     * dal database
     */
    public function deleteAction()
    {
        if ($this->getRequest()->isPost()) 
        {
            // Imposta la variabile con il valore del pulsante premuto
            $del = $this->getRequest()->getPost('del');
            
            if ($del == 'Sì') 
            {
                // Se premuto il pulsante 'Sì' elimina la riga dal database
                $id = $this->getRequest()->getPost('id');
                $books = new Application_Model_DbTable_Books();
                $books->deleteBook($id);
            }
            
            // Reindirizza alla pagina principale
            $this->_helper->redirector('index');
            
        } 
        else 
        {
            // Popola la pagina con il libro che si vuole eliminare
            $id = $this->_getParam('id', 0);
            $books = new Application_Model_DbTable_Books();
            $this->view->book = $books->getBook($id);
        }
    }

La vista sarà composta principalmente da due pulsanti che ci permetteranno di confermare o meno l’eliminazione del libro.

Inseriamo anche in questo caso un nuovo file, chiamato delete.phtml, nella cartella:

  • application -> views -> scripts -> index

con il seguente codice:

<p>Vuoi eliminare
  '<?php echo $this->escape($this->book['titolo']); ?>' di 
  '<?php echo $this->escape($this->book['scrittore']); ?>'?
</p>

<form action="<?php echo $this->url(array('action'=>'delete')); ?>" method="post">
	<div>
	  <input type="hidden" name="id" value="<?php echo $this->book['id']; ?>" />
	  <input type="submit" name="del" value="Sì" />
	  <input type="submit" name="del" value="No" />
	</div>
</form>

L’ultima cosa da fare è visualizzare per ogni libro un ulteriore link per poterlo cancellare:

<html> 
<head>	
</head>
<body>

<table>

	<tr>
	    <th>Autore</th>
	    <th>Libro</th>
	</tr>
	
	<?php foreach($this->books as $book) : ?>
	<tr>
		<td><?php echo $this->escape($book->scrittore);?></td>
	    <td><?php echo $this->escape($book->titolo);?></td>
	    <td>
        	<a href="<?php echo $this->url(array('controller'=>'index', 
            	'action'=>'edit', 'id'=>$book->id));?>">Modifica</a>
            	
        <a href="<?php echo $this->url(array('controller'=>'index', 
            'action'=>'delete', 'id'=>$book->id));?>">Elimina</a>
        </td>
	</tr>
	<?php endforeach; ?>
	
</table>

<p>
	<a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'add'));?>">Aggiungi un libro</a>
</p>

</body>
</html>

Un po’ di CSS per concludere

Concludiamo il post aggiungendo al nostro applicativo un foglio di stile così da poter formattare le pagine html a nostro piacimento.

Creiamo una nuova cartella sotto public, chiamiamola css e all’interno di essa generiamo il file style.css

Inseriamo nel file appena creato il seguente codice:

body,html {
    margin: 50px 0 0 150px;
    font-family: Verdana, arial;
}

th {
    text-align: center;
}
td, th {
    padding-right: 10px;
}

e scriviamo tra i tag di head della pagina index.phtml la riga di php:

<head>
	<?php echo $this->headLink()->prependStylesheet($this->baseUrl().'/css/style.css'); ?>
</head>

Non appena ricaricheremo la pagina, vedremo applicata la nuova formattazione alla pagina principale dell’applicativo.

Conclusioni

Con il post di oggi abbiamo completato la nostra libreria fornendola di nuove funzionalità dopo che nel primo e secondo post avevamo rispettivamente:

  • impostato l’ambiente di sviluppo e creato lo scheletro del progetto;
  • configurata l’applicazione e analizzato il pattern MVC da applicare per lo sviluppo della libreria.

Attraverso questo mini tutorial abbiamo cercato di fare una panoramica sul framework della Zend Technologies, analizzando gli aspetti principali che lo compongono.

Se in futuro ne avremo l’opportunità, cercheremo di vedere più da vicino alcune features interessanti come l’integrazione con la libreria JavaScript Dojo Toolkit oppure con un prodotto ORM come Doctrine 2.

Alla prossima!

3 Posts

Sono laureato in Ingegneria Informatica e lavoro dal 2009 presso OmniaGroup dove ricopro il ruolo di Senior Developer. Sviluppo principalmente applicazioni web su piattaforma J2EE utilizzando IBM Websphere 6.1/7.0, JPA (Eclipselink), EJB3 e JSF (RichFaces). Lavoro anche nella realizzazione di processi di Business Intelligence con strutture di ipercubi sia di tipo ROLAP (attraverso SAP Business Object) che di tipo MOLAP (con la suite Oracle Hyperion) e con il supporto del Data warehouse Teradata.