This post is to share the php/zend framework code I used to create an rsvp for my wedding site. I’m not going into all the details since that would take too long ;p but all the code is available if you want to use it. This was created using the zend framework version 1.7.
So I’m getting married in two month and for our wedding my fiancee and I decided to create a website for our guests. The site includes information such as location, time, links to registries, maps, and a section to rsvp. The site was made by my fiancee in html and css. When she was done, I ported it over to zend framework and started creating the rsvp section which I’ll describe next. You can view the finished wedding site here:

http://www.joeyrivera.com/wedding
The objectives of the rsvp are the following:
- Allow guest to enter their code
- each invitation that goes out has a code in it specific to the ‘family’.
- Validate code from database and load information about that family
- return the family name and how many seats they have available. Because of seating limitations, we only allow x amounts of seats per family. Ex: A friend could have 2 seats available in case they are coming with a guest.
- Let guest select if they attending, if so, select how many guests are coming with an optional comments field
- Submit and save their rsvp in the database and email us with the details
The database structure is very simple, only one table that looks like:
CREATE TABLE `family` (
`family_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`alias` VARCHAR(100) NOT NULL,
`code` SMALLINT(5) UNSIGNED NOT NULL DEFAULT ‘0′,
`attending` TINYINT(1) DEFAULT NULL,
`available_seats` TINYINT(3) UNSIGNED NOT NULL,
`confirmed_seats` TINYINT(3) UNSIGNED DEFAULT NULL,
`comments` VARCHAR(255) DEFAULT NULL,
`last_access` DATETIME DEFAULT NULL,
PRIMARY KEY (`family_id`),
UNIQUE KEY `Index_2` USING BTREE (`code`)
) ENGINE=INNODB AUTO_INCREMENT=80 DEFAULT CHARSET=latin1;
The fields are:
- Alias is the ‘description or name’ for the family such as Ashley and Joey Rivera or The Rivera’s.
- Code is the unique code we send out with each invitation.
- Attending is a boolean that is updated when the guest rsvps.
- Available seats is the number we set to limit how many people can come from that family.
- Confirmed seats is the number the guest sets when rsvping.
- Comments is optional
- Last access tracks the last time that row was updated
I made code unique because it should be, we don’t want to accidentally assign two codes to the same family. We don’t want to use the family id as the code because we want the code a bit harder to guess if someone feels like fooling around with the system – we are hoping our family members and friends won’t purposely try to break the system though :p.
Here is the code:
class RsvpController extends Zend_Controller_Action
{
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper(‘Redirector’);
}
public function indexAction()
{
$this->view->form = $this->rsvpForm();
}
public function submit1Action()
{
// get and filter code
$filters = array(
‘*’ => ‘StringTrim’
);
$validators = array(
‘Digits’
);
$input = new Zend_Filter_Input($filters, $validators, $this->getRequest()->getParams());
// verify code was passed
if(!$input->isValid(‘code’))
{
// go back with error message
$this->_redirect(‘/rsvp’);
}
$code = $input->code;
// get family from code
$family = new Family();
$family_row = $family->fetchRow(‘code = ‘ . $code . ”);
// if family doesn’t exist, leave
if(empty($family_row))
{
$this->_redirect(‘/rsvp’);
}
// track row in session
$session = new Zend_Session_Namespace(‘family’);
$session->code = $code;
$session->row = $family_row;
// all is good, give view data
$this->view->family = $family_row;
$this->view->form = $this->familyForm($family_row);
}
public function submit2Action()
{
// validate session
$session = new Zend_Session_Namespace(‘family’);
if(!isset($session->row))
{
$this->_redirect(‘/’);
return;
}
$form = $this->familyForm($session->row);
// get vars to check
$attending = $this->getRequest()->getParam(‘attending’);
$seats = $this->getRequest()->getParam(’seats’);
// make sure data is good
// if attending but seats is 0 then ask them to select how many seats
// if the seats is greater than available seats error out
if(($attending && !$seats) || ($attending > $session->row->available_seats))
{
// assumed by passing error on element would trigger this but doesn’t seem too
$form->markAsError();
$seats_element = $form->getElement(’seats’);
$seats_element->addError(‘Please select how many people are coming.’);
}
//else if
// if not attending but selected seats, ask them about it
if(!$attending && $seats)
{
$form->markAsError();
$attending_element = $form->getElement(‘attending’);
$attending_element->addError(‘You selected you are not coming but set the number
of seat to a number greater than 0. Did you mean to say you are attending?’);
}
// if the form has an error, it can still be valid so need to check for both
if($form->isErrors() || !$form->isValid($_POST))
{
$form->populate($_POST); // for some reason have to manually call this or values don’t show
$this->view->form = $form;
$this->view->family = $session->row;
$this->render(‘index’);
return;
}
// update family
$family = new Family();
$family->update(array(
‘attending’ => $form->getValue(‘attending’) ,
‘confirmed_seats’ => $form->getValue(’seats’) ,
‘comments’ => $form->getValue(‘comments’) ,
‘last_access’ => date(‘Y-m-d H:i:s’)
), ‘code = ‘ . $session->code . ”);
// email
$mail = new Zend_Mail();
$mail->setBodyText(‘New RSVP submitted.’);
$mail->setBodyHtml(‘<p>New RSVP submitted:</p>
<p>’ . $session->row->alias . ‘</p>
<p>Attending: ‘ . $form->getValue(‘attending’) . ‘</p>
<p>Seats: ‘ . $form->getValue(’seats’) . ‘</p>
<p>Comments: ‘ . $form->getValue(‘comments’) . ‘ </p>’);
$mail->setFrom(‘joey@joeyrivera.com’, ‘JoeyRivera.com’);
$mail->addTo(‘joey1.rivera@gmail.com’, ‘Joey Rivera’);
$mail->addTo(‘person@person.com’, ‘Ashley Fleishel’);
$mail->setSubject(‘Wedding New RSVP’);
$mail->send();
$this->_redirect(‘/rsvp/done’);
}
public function doneAction()
{
// unset session
$session = new Zend_Session_Namespace(‘family’);
$session->unsetAll();
}
private function rsvpForm()
{
$form = new Zend_Form();
$form->setAction(‘/rsvp/submit1′)->setMethod(‘post’)->setAttrib(‘id’, ‘rsvp’);
$form->addElement(‘text’, ‘code’, array(
‘label’ => ‘RSVP Code (found on your invitation)’ ,
‘validators’ => array(
‘digits’
) , ‘required’ => true
));
$form->addElement(’submit’, ’submit’);
return $form;
}
private function familyForm($family)
{
$form = new Zend_Form();
$form->setAction(‘/rsvp/submit2′)->setMethod(‘post’)->setAttrib(‘id’, ‘rsvp’);
$form->addElement(‘radio’, ‘attending’, array(
‘label’ => ‘Are you attending?’ ,
‘multiOptions’ => array(1 => ‘Yes’ , 0 => ‘No’) ,
‘validators’ => array(
‘Digits’
) , ‘required’ => true
));
// create array of seats
$seats = array();
for($x = 0, $max = $family->available_seats; $x <= $max; $x++)
{
$seats[$x] = $x;
}
// limit number to available seats from row session
$form->addElement(’select’, ’seats’, array(
‘label’ => ‘How many will be attending?’ ,
‘multiOptions’ => $seats ,
‘required’ => true
));
$form->addElement(‘textarea’, ‘comments’, array(
‘label’ => ‘Comments’ , //’validators’ => array(
// ‘Alnum’
//),
‘required’ => false , ‘width’ => 250
));
$form->addElement(’submit’, ’submit’);
return $form;
}
}
I’ll summarize what I’m doing with the code. I have 4 actions in my RsvpController:
index
- This action display the rsvpForm in the view which is a input box for the guests to type in their family code.
submit1 (I know, name sucks but I was going for something quick ;p)
- This action will validate the code submitted by the index action.
- It then creates an instance of family using a zend db table model and loads the data from the database for the family that matches that code.
- If it’s a real family, a session var is created with the family data and the form familyForm is displayed. Else, the user is taken back to the index action.
submit2
- When the familyForm is submitted in submit1, this action validates that there is a family session var.
- Then it does a few validations more such as making sure that the family seats is a number greater than 0 if they are attending. Or didn’t choose a number of seats greater than 0 if they are not attending (in case they accidentally hit not coming but did want to).
- Then it validates the submitted form – I put it at the end because it seemed as if it would be less code that way. You can read the comments to see why I did what I did, I had some issues with the way I was expecting the form zend framework class to behave.
- If all is well, the family row in the database is updated and an email is sent to myself and fiancee.
done
- Displays a done message and the rsvp process is complete!
That’s about it. A couple quick thoughts or comments about this. The form could be made more secure but like I said before, for this project I think it’s fine. Also, you’ll see a bunch of css in the views, it’s because I was trying to port the site over quickly and that was the quickest way. If you have any specific questions feel free to ask. Hope you find this useful. Below are some screen shots of the final product and a zip file of the code including the model, the rsvp controller, and the views in the application folder:
index:

submit1:

done:







#1 by Ashley CF on August 6, 2009 - 10:59 am
Quote
Works great! The ones that come with the stock wedding websites don’t seem to work well.
#2 by enrique on January 24, 2010 - 4:52 pm
Quote
Hi I was looking for something like this for my friends wedding.
I was just looking at the files but don’t see a file called submit 2. Is it missing?
Should I copy and paste the files in the formated folders into my main directory?
Thanks so much.
#3 by Joey on January 25, 2010 - 8:52 am
Quote
Enrique,
The submit2 action doesn’t have a view file associated with it. It will either renders another view or redirect depending on what happens.
What do you mean by formated folders? To use this code as is, you will need to be using the Zend Framework (I used 1.7 for this project). You can create a new empty project and then replace your application folder with the files from the zip file provided above.
#4 by enrique on January 25, 2010 - 8:12 pm
Quote
Thanks Joey for the reply.
Yeah, just realized that the php structure is a little different with the Zend Framework.
I’m structuring my friends site using OScommerce. The php is a bit different.
Now very good with php and sql but I’m going to see if I can play with your code and see if I can make it work somehow.
Thanks,
#5 by Benjamin on February 8, 2010 - 7:21 pm
Quote
Hi Joey, I really like your script and want to put it on our site… though I’m really stuck on how to assemble it in my domain space and php/mysql database. Basically I am a dummy and need to know how to assemble it. Exactly how do I set up Zend Framework on my site and how does it work in compliance to this code/applet?
#6 by Joey on February 9, 2010 - 2:55 pm
Quote
Benjamin,
If there was an easy way of explaining how to set this up I would but I’m afraid I will just confuse you more and cause you to waste time. The code I offer here is more of ‘as is’ for people to use at their discretion. If you are really interested in using this code and the Zend Framework, I recommend you start with their quick start guide:
http://framework.zend.com/manual/en/learning.quickstart.intro.html
#7 by Benjamin on February 11, 2010 - 10:09 pm
Quote
Joey, thanks for replying, I will be sure to give it a read… and congratulations on the marriage!
#8 by Son on March 7, 2010 - 3:02 pm
Quote
Wow, this is an amazing script. I’d love to use this on my website for our wedding, but our web hosting doesn’t have zend or a way to modify the php.ini so there goes that idea!
Good job on the codes though Joey. Congrats also and have a wonderful marriage
#9 by Joey on March 8, 2010 - 9:00 am
Quote
Thank you. Just to let you know, to use the zend framework only required the framework library which is a free download from their site. Other than that, if you have the proper version of PHP you should be able to run zend in your server. Here is their quick start guide if you want more information: http://framework.zend.com/manual/en/learning.quickstart.html
#10 by Clover on June 11, 2010 - 9:49 am
Quote
Hi Joey, I really like your script. I’m working on an asp.net wedding website with an RSVP and this is the best example I’ve come across after a 7 hour web trawl (yes; even though it’s php!) Thanks & Congratulations!
#11 by Joey on June 11, 2010 - 9:59 am
Quote
I’m glad to hear you found this information helpful. Good luck on your site.
#12 by Bosbeer on July 14, 2010 - 1:31 pm
Quote
Thanks a lot! I’m glad to see someone is willing to share their knowledge! Awesome stuff!