CakePHP Contact Form – Quick and Dirty

Page content

I must say, this was a major hurdle for me when I first started out with CakePHP. If you’re working with some data from a database, then it’s all Model-View-Controller magic. Your forms are automatic: $form->input() is pretty much all you need. Why is this? That’s because all the information about the fields (names, sizes, types, etc.) come straight from the database.

You’re Out On Your Own

The problem right now is that, you’re all on your own. You need to describe your data on your own. So, on with it:

Here’s your model code:

class Contact extends AppModel {
	var $name = 'Contact';
	var $useTable = false;  // Not using the database, of course.

	// All the fancy validation you could ever want.
	var $validate = array(
	    'name' => array(
	        'rule' => '/.+/',
			'allowEmpty' => false,
	        'required' => true,
	    ),
		'subject' => array(
	        'rule' => array('minLength', 5),
			'message' => 'Subject must be 5 characters long'
	    ),
		'email' => array(
	        'rule' => 'email',
			'message' => 'Please enter a valid email address'
	    ),
	);

	// This is where the magic happens
	function schema() {
		return array (
			'name' => array('type' => 'string', 'length' => 60),
			'email' => array('type' => 'string', 'length' => 60),
			'message' => array('type' => 'text', 'length' => 2000),
			'subject' => array('type' => 'string', 'length' => 100),
		);
	}
}

What The User Sees

I think the model’s the hardest part. The view is ridiculous:

echo $form->create(null, array('action' => 'index'));
	echo $form->input('name');
	echo $form->input('email');
	echo $form->input('subject');
	echo $form->input('message');
	echo $form->submit();
	echo $form->end();

I know; you’re disappointed right? Sorry.

How Do We Control All This?

So, here’s your controller. I was going to leave that up to you, but it’s so simple that I can’t help it:

class ContactController extends AppController
{
	var $name = 'Contact';
	var $uses = 'Contact';
	var $helpers = array('Html', 'Form', 'Javascript');
	var $components = array('Email', 'Session');
	function index(){
		if(isset($this->data)) {
			$this->Contact->create($this->data);
			// There is no save(), so we need to validate manually.
			if($this->Contact->validates()){
				$this->Email->to = Configure::read('CONTACT_EMAIL');
				$this->Email->replyTo = $this->data['Contact']['email'];
				$this->Email->from = $this->data['Contact']['name'].' <'.$this->data['Contact']['email'].'>';
				$this->Email->subject = 'Contact Form: '.$this->data['Contact']['subject'];
				//$this->Email->delivery = 'debug';
				if ($this->Email->send($this->data['Contact']['message'])) {
					$this->Session->setFlash('Thank you for contacting us');
					//$this->redirect('/');
				} else {
					$this->Session->setFlash('Mail Not Sent');
				}
				$this->redirect(array('action' => 'index'));
			} else {
				$this->Session->setFlash('Please Correct Errors');
				//$this->redirect('/contacts');
			}
		}
	}
}

After I got halfway through this, I remembered that Snook had written something very similar, sorry J.

There’s one subtle difference that I’ve noticed, that I need to point out.

_var $schema as apposed to function schema(). In the original CakePHP code, one of the major actions of Model::function() is to return _var Model::$shema. So, Tom-ay-to/Tom-a-to; it really doesn’t matter.