Forms and actions
Adding new albums
We can now code up the functionality to add new albums. There are two bits to this part:
- Display a form for user to provide details.
- Process the form submission and store to database.
We will use zend-form to do this. zend-form manages the various form inputs as well as their validation, the latter of which is handled by the zend-inputfilter component. We'll start by creating a new class, AlbumFormAlbumForm
, extending from ZendFormForm
. Create the filemodule/Album/src/Form/AlbumForm.php
with the following contents:
namespace AlbumForm;
use ZendFormForm;
class AlbumForm extends Form
{
public function __construct($name = null)
{
// We will ignore the name provided to the constructor
parent::__construct('album');
$this->add([
'name' => 'id',
'type' => 'hidden',
]);
$this->add([
'name' => 'title',
'type' => 'text',
'options' => [
'label' => 'Title',
],
]);
$this->add([
'name' => 'artist',
'type' => 'text',
'options' => [
'label' => 'Artist',
],
]);
$this->add([
'name' => 'submit',
'type' => 'submit',
'attributes' => [
'value' => 'Go',
'id' => 'submitbutton',
],
]);
}
}
Within the constructor of AlbumForm
we do several things. First, we set the name of the form as we call the parent's constructor. The, we create four form elements: the id, title, artist, and submit button. For each item we set various attributes and options, including the label to be displayed.
Form method
HTML forms can be sent using
POST
andGET
. zend-form defaults toPOST
; therefore you don't have to be explicit in setting this option. If you want to change it toGET
however, set the method attribute in the constructor:$this->setAttribute('method', 'GET');
We also need to set up validation for this form. zend-inputfilter provides a general purpose mechanism for input validation. It also provides an interface,InputFilterAwareInterface
, which zend-form will use in order to bind an input filter to a given form. We'll add this capability now to our Album
class.
// module/Album/src/Model/Album.php:
namespace AlbumModel;
// Add the following import statements:
use DomainException;
use ZendInputFilterInputFilter;
use ZendInputFilterInputFilterAwareInterface;
use ZendInputFilterInputFilterInterface;
class Album implements InputFilterAwareInterface
{
public $id;
public $artist;
public $title;
// Add this property:
private $inputFilter;
public function exchangeArray(array $data)
{
$this->id = ! empty($data['id']) ? $data['id'] : null;
$this->artist = ! empty($data['artist']) ? $data['artist'] : null;
$this->title = ! empty($data['title']) ? $data['title'] : null;
}
public function getArrayCopy()
{
return [
'id' => $this->id,
'artist' => $this->artist,
'title' => $this->title,
];
}
/* Add the following methods: */
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new DomainException(sprintf(
'%s does not allow injection of an alternate input filter',
__CLASS__
));
}
public function getInputFilter()
{
if ($this->inputFilter) {
return $this->inputFilter;
}
$inputFilter = new InputFilter();
$inputFilter->add([
'name' => 'id',
'required' => true,
'filters' => [
['name' => 'int'],
],
]);
$inputFilter->add([
'name' => 'artist',
'required' =>