Skip to content
This repository has been archived by the owner on Nov 28, 2018. It is now read-only.

Step 2: View Preparation and Data Processing

timasplin edited this page Aug 23, 2011 · 6 revisions

Next we are going to setup our controller to handle each of the steps in the form wizard.

Very important: Rather than creating a separate controller action for each of the steps in the form, all the steps are tied together through one action (the default is ‘wizard’). This means, for our example, our urls will look like example.com/signup/wizard/account etc. This way, everything is handle by the component and customization is handled through controller callbacks.

Because of this, the wizard action itself can be very basic. It merely needs to pass the step requested to the component’s main method – process():

Controller Class:

<?php 
class SignupController extends AppController {
	var $components = array('Wizard.Wizard');

	function beforeFilter() {
		$this->Wizard->steps = array('account', 'address', 'billing', 'review');
	}

	function wizard($step = null) {
		$this->Wizard->process($step);
	}
}
?>

Something to consider if your wizard is the controller’s main feature (as it would be in our example), is to route the default action for the controller to the wizard action. This would allow prettier links such as example.com/signup to be handled by SignupController::wizard(), which would then redirect to /signup/wizard/account (or the first incomplete step in the wizard).

Router::connect('/signup', array('controller' => 'signup', 'action' => 'wizard'));

Next, we are going to create controller callbacks to handle each step. Each step has two controller callbacks: prepare and process.

The prepare callback is optional and occurs before the step’s view is loaded. This is a good place to set any data or variables that you want available for the view. The name of the callback is _prepareStepName. So for our example, our prepare callbacks would be _prepareAccount(), _prepareAddress(), etc.

The process callback is required and occurs after data has been posted. This is where data validation should be handled. The process callback must return either true or false. If true, the wizard will continue to the next step; if false, the user will remain on the step and any validation errors will be presented. The name of the callback is _processStepName. So for our example, our process callbacks would be _processAccount(), _processAddress(), etc. You do not have to worry about retaining data as this is handled automatically by the component. Data retrieval will be discussed later in the tutorial.

It’s very important to note that every step in the wizard must contain a form with a field. The only way for the wizard to continue to the next step is for the process callback to return true. And the process callback is only called if $this->data is not empty.

So lets create some basic process callbacks. Real world examples would most likely be more complicated, but this should give you the basic idea (don’t forget to add any needed models):

Controller Class:

<?php 
class SignupController extends AppController {
	var $uses = array('Client', 'User', 'Billing');
	var $components = array('Wizard.Wizard');

	function beforeFilter() {
		$this->Wizard->steps = array('account', 'address', 'billing', 'review');
	}

	function wizard($step = null) {
		$this->Wizard->process($step);
	}
/**
 * [Wizard Process Callbacks]
 */
	function _processAccount() {
		$this->Client->set($this->data);
		$this->User->set($this->data);

		if($this->Client->validates() && $this->User->validates()) {
			return true;
		}
		return false;
	}

	function _processAddress() {
		$this->Client->set($this->data);

		if($this->Client->validates()) {
			return true;
		}
		return false;
	}

	function _processBilling() {
		$this->Billing->set($this->data);

		if($this->Billing->validates()) {
			return true;
		}
		return false;
	}

	function _processReview() {
		return true;
	}
}
?>

Step 3: Data Retrieval and Wizard Completion