Here's the parent class:
here's the parent class:
<?php
class ZervWizard
{
var $_complete = false;
var $_steps = array();
var $_currentStep = null;
var $_containerPrefix = '__wiz_';
var $_errors = array();
var $_step_status_key = '__step_complete';
var $_step_expected_key = '__expected_action';
var $options = array('redirectAfterPost' => true);
var $resetAction = '__reset';
function ZervWizard(&$container, $name)
{
if (!is_array($container)) {
$this->addError('container', 'Container not valid');
return;
}
$containerKey = $this->_containerPrefix . $name;
if (!array_key_exists($containerKey, $container))
$container[$containerKey] = array();
$this->container = &$container[$containerKey];
if (!array_key_exists('_errors', $this->container))
$this->container['_errors'] = array();
$this->_errors = &$this->container['_errors'];
}
function process($action, &$form, $process = true)
{
if ($action == $this->resetAction) {
$this->clearContainer();
$this->setCurrentStep($this->getFirstIncompleteStep());
}
else if (isset($form['previous']) && !$this->isFirstStep()) {
$this->_errors = array();
$this->setCurrentStep($this->getPreviousStep($action));
$this->doRedirect();
}
else {
$proceed = false;
if (strlen($action) == 0)
$action = $this->getExpectedStep();
if ($this->stepCanBeProcessed($action)) {
if ($this->getStepNumber($action) <= $this->getStepNumber($this->getExpectedStep()))
$proceed = true;
else
$proceed = false;
}
if ($proceed) {
if ($process) {
$this->_errors = array();
$callback = 'process_' . $action;
$complete = method_exists($this, $callback) && $this->$callback($form);
$this->container[$this->_step_status_key][$action] = $complete;
if ($complete)
$this->setCurrentStep($this->getFollowingStep($action)); // all ok, go to next step
else
$this->setCurrentStep($action); // error occurred, redo step
// final processing once complete
if ($this->isComplete())
$this->completeCallback();
$this->doRedirect();
}
else
$this->setCurrentStep($action);
}
else // when initally starting the wizard
$this->setCurrentStep($this->getFirstIncompleteStep());
}
// setup any required data for this step
$callback = 'prepare_' . $this->getStepName();
if (method_exists($this, $callback))
$this->$callback();
}
function completeCallback()
{ }
function doRedirect()
{
if ($this->coalesce($this->options['redirectAfterPost'], false)) {
$redir = $_SERVER['REQUEST_URI'];
$redir = preg_replace('/\?' . preg_quote($_SERVER['QUERY_STRING'], '/') . '$/', '', $redir);
header('Location: ' . $redir);
exit;
}
}
function isComplete()
{
return $this->_complete;
}
function setCurrentStep($step)
{
if (is_null($step) || !$this->stepExists($step)) {
$this->_complete = true;
$this->container[$this->_step_expected_key] = null;
}
else {
$this->_currentStep = $step;
$this->container[$this->_step_expected_key] = $step;
}
}
function getExpectedStep()
{
$step = $this->coalesce($this->container[$this->_step_expected_key], null);
if ($this->stepExists($step))
return $step;
return null;
}
function stepExists($stepname)
{
return array_key_exists($stepname, $this->_steps);
}
function getStepName()
{
return $this->_currentStep;
}
function getStepNumber($step = null)
{
$steps = array_keys($this->_steps);
$numSteps = count($steps);
if (strlen($step) == 0)
$step = $this->getStepName();
$ret = 0;
for ($n = 1; $n <= $numSteps && $ret == 0; $n++) {
if ($step == $steps[$n-1])
$ret = $n;
}
return $ret;
}
function stepCanBeProcessed($step)
{
$steps = array_keys($this->_steps);
$numSteps = count($steps);
for ($i = 0; $i < $numSteps; $i++) {
$_step = $steps[$i];
if ($_step == $step)
break;
if (!$this->container[$this->_step_status_key][$_step])
return false;
}
return true;
}
function getStepProperty($key, $default = null)
{
$step = $this->getStepName();
if (isset($this->_steps[$step][$key]))
return $this->_steps[$step][$key];
return $default;
}
function getFirstStep()
{
$steps = array_keys($this->_steps);
return count($steps) > 0 ? $steps[0] : null;
}
function getFirstIncompleteStep()
{
$steps = array_keys($this->_steps);
$numSteps = count($steps);
for ($i = 0; $i < $numSteps; $i++) {
$_step = $steps[$i];
if (!array_key_exists($this->_step_status_key, $this->container) || !$this->container[$this->_step_status_key][$_step])
return $_step;
}
return null;
}
function getPreviousStep($step)
{
$ret = null;
$steps = array_keys($this->_steps);
$done = false;
foreach ($steps as $s) {
if ($s == $step) {
$done = true;
break;
}
$ret = $s;
}
return $ret;
}
function getFollowingStep($step)
{
$ret = null;
$steps = array_keys($this->_steps);
$ready = false;
foreach ($steps as $s) {
if ($s == $step)
$ready = true;
else if ($ready) {
$ret = $s;
break;
}
}
return $ret;
}
function addStep($stepname, $title)
{
if (array_key_exists($stepname, $this->_steps)) {
$this->addError('step', 'Step with name ' . $stepname . ' already exists');
return;
}
$this->_steps[$stepname] = array('title' => $title);
if (!array_key_exists($this->_step_status_key, $this->container))
$this->container[$this->_step_status_key] = array();
if (!array_key_exists($stepname, $this->container[$this->_step_status_key]))
$this->container[$this->_step_status_key][$stepname] = false;
}
function isFirstStep()
{
$steps = array_keys($this->_steps);
return count($steps) > 0 && $steps[0] == $this->getStepName();
}
function isLastStep()
{
$steps = array_keys($this->_steps);
return count($steps) > 0 && array_pop($steps) == $this->getStepName();
}
function setValue($key, $val)
{
$this->container[$key] = $val;
}
function getValue($key, $default = null)
{
return $this->coalesce($this->container[$key], $default);
}
function clearContainer()
{
foreach ($this->container as $k => $v)
unset($this->container[$k]);
}
function coalesce(&$var, $default = null)
{
return isset($var) && !is_null($var) ? $var : $default;
}
function addError($key, $val)
{ $this->_errors[$key] = $val; }
function isError($key = null)
{
if (!is_null($key))
return array_key_exists($key, $this->_errors);
return count($this->_errors) > 0;
}
function getError($key)
{
return array_key_exists($key, $this->_errors) ? $this->_errors[$key] : null;
}
}
?>
Does that help?