diff --git a/Controller/Component/WizardComponent.php b/Controller/Component/WizardComponent.php index 735d265..9ee8bb0 100644 --- a/Controller/Component/WizardComponent.php +++ b/Controller/Component/WizardComponent.php @@ -205,6 +205,13 @@ class WizardComponent extends Component { */ protected $_wizardUrl = array(); +/** + * Holds the array with steps and branches from the initial Wizard configuration. + * + * @var array + */ + protected $_stepsAndBranches = array(); + /** * Initializes WizardComponent for use in the controller * @@ -216,6 +223,7 @@ class WizardComponent extends Component { public function initialize(Controller $controller) { $this->controller = $controller; $this->__setSessionKeys(); + $this->_stepsAndBranches = $this->steps; } /** @@ -244,9 +252,8 @@ private function __setSessionKeys() { */ public function startup(Controller $controller) { $this->__setSessionKeys(); - $this->steps = $this->_parseSteps($this->steps); $this->config('action', $this->action); - $this->config('steps', $this->steps); + $this->_configSteps($this->steps); if (!in_array('Wizard.Wizard', $this->controller->helpers) && !array_key_exists('Wizard.Wizard', $this->controller->helpers)) { $this->controller->helpers['Wizard.Wizard'] = array( 'sessionRootKey' => $this->sessionRootKey, @@ -254,6 +261,18 @@ public function startup(Controller $controller) { } } +/** + * Parses the steps array by stripping off nested arrays not included in the branches + * and writes a simple array with the correct steps to session. + * + * @param array $steps Array to be parsed for nested arrays. + * @return void + */ + protected function _configSteps($steps) { + $this->steps = $this->_parseSteps($steps); + $this->config('steps', $this->steps); + } + /** * Parses the steps array by stripping off nested arrays not included in the branches * and returns a simple array with the correct steps. @@ -510,6 +529,9 @@ protected function _validStep($step) { * @return void */ protected function _setCurrentStep($step) { + if (!in_array($step, $this->steps)) { + return; + } $this->_currentStep = reset($this->steps); while (current($this->steps) != $step) { $this->_currentStep = next($this->steps); @@ -556,6 +578,8 @@ public function save($step = null, $data = null) { $data = $this->controller->request->data; } $this->controller->Session->write("$this->_sessionKey.$step", $data); + $this->_getExpectedStep(); + $this->_setCurrentStep($step); } /** @@ -603,6 +627,7 @@ public function branch($name, $skip = false) { } $branches[$name] = $value; $this->controller->Session->write($this->_branchKey, $branches); + $this->_configSteps($this->_stepsAndBranches); } /** @@ -674,6 +699,7 @@ public function delete($key = null) { */ public function unbranch($branch) { $this->controller->Session->delete("$this->_branchKey.$branch"); + $this->_configSteps($this->_stepsAndBranches); } } diff --git a/Test/Case/Controller/Component/WizardComponentTest.php b/Test/Case/Controller/Component/WizardComponentTest.php index 01e0034..81e6145 100644 --- a/Test/Case/Controller/Component/WizardComponentTest.php +++ b/Test/Case/Controller/Component/WizardComponentTest.php @@ -23,6 +23,7 @@ class WizardUserMock extends Model { /** * AuthTestController class * + * @property WizardComponent $Wizard * @package Wizard.Test.Case.Controller.Component */ class WizardTestController extends Controller { @@ -71,6 +72,22 @@ public function processStep2() { return false; } + public function processGender() { + if (!empty($this->request->data)) { + if ($this->Wizard->defaultBranch === false) { + if ($this->request->data['WizardUserMock']['gender'] == 'female') { + $this->Wizard->unbranch('male'); + $this->Wizard->branch('female'); + } else { + $this->Wizard->unbranch('female'); + $this->Wizard->branch('male'); + } + } + return true; + } + return false; + } + public function processStep3() { if (!empty($this->request->data)) { return true; @@ -136,7 +153,7 @@ public function setUp() { */ public function tearDown() { parent::tearDown(); - $this->Wizard->Session->delete('Wizard'); + CakeSession::destroy(); unset($this->Controller, $this->Wizard); } @@ -374,6 +391,87 @@ public function testProcessStepOnePost() { $this->assertEquals($expectedSession, $resultSession); } +/** + * Tests 'autoAdvance' and 'defaultBranch' settings set to false and manual call to `branch()`. + * + * @return void + */ + public function testProcessGenderPost() { + $this->Wizard->Session->delete('Wizard'); + unset($this->Controller, $this->Wizard); + $CakeRequest = new CakeRequest(null, false); + $CakeResponse = $this->getMock('CakeResponse', array('send')); + $this->Controller = new WizardTestController($CakeRequest, $CakeResponse); + $this->Controller->components['Wizard.Wizard']['autoAdvance'] = false; + $this->Controller->components['Wizard.Wizard']['defaultBranch'] = false; + $ComponentCollection = new ComponentCollection(); + $ComponentCollection->init($this->Controller); + $this->Controller->Components->init($this->Controller); + $this->Wizard = $this->Controller->Wizard; + $this->Wizard->initialize($this->Controller); + + // Set session prerequisites. + $session = array( + 'config' => array( + 'steps' => array( + 'step1', + 'step2', + 'gender', + 'confirmation', + ), + 'action' => 'wizard', + 'expectedStep' => 'gender', + 'activeStep' => 'gender', + ), + 'WizardTest' => array( + 'step1' => array(), + 'step2' => array(), + ), + ); + $this->Wizard->Session->write('Wizard', $session); + + $this->Wizard->startup($this->Controller); + $postData = array( + 'WizardUserMock' => array( + 'gender' => 'female', + ), + ); + $this->Wizard->controller->request->data = $postData; + $CakeResponse = $this->Wizard->process('gender'); + + $expectedSession = array( + 'branches' => array( + 'WizardTest' => array( + 'female' => 'branch', + ), + ), + 'config' => array( + 'steps' => array( + 'step1', + 'step2', + 'gender', + 'step4', + 'step5', + 'confirmation', + ), + 'action' => 'wizard', + 'expectedStep' => 'step4', + 'activeStep' => 'gender', + ), + 'WizardTest' => array( + 'step1' => array(), + 'step2' => array(), + 'gender' => $postData, + ), + ); + $resultSession = $this->Wizard->Session->read('Wizard'); + $this->assertEquals($expectedSession, $resultSession); + + $this->assertInstanceOf('CakeResponse', $CakeResponse); + $headers = $CakeResponse->header(); + $this->assertContains('/wizard/step4', $headers['Location']); + } + public function testProcessAutovalidatePost() { // Set session prerequisites. $session = array(