Created
March 25, 2015 13:53
-
-
Save tom--/94b67846991a381f73ca to your computer and use it in GitHub Desktop.
Controller class for Yii 2 to support a wizard using one form model and several actions with branching logic.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace spinitron\controllers; | |
| use Yii; | |
| use yii\web\Controller; | |
| use yii\web\Session; | |
| class WizardController extends Controller | |
| { | |
| /** | |
| * @var \yii\base\Model Class name of the Wizard's form model | |
| */ | |
| static $formClass; | |
| /** | |
| * @var string Route of the first form of the wizard. | |
| */ | |
| static $startRoute = 'index'; | |
| /** | |
| * @var Session | |
| */ | |
| protected $session; | |
| /** | |
| * @var string | |
| */ | |
| protected $step; | |
| /** | |
| * @var array | |
| */ | |
| protected $attributes; | |
| public function beforeAction($action) | |
| { | |
| if (!parent::beforeAction($action)) { | |
| return false; | |
| } | |
| $this->session = Yii::$app->session; | |
| if (!$this->session->isActive) { | |
| $this->session->open(); | |
| } | |
| if ($this->session->has('step')) { | |
| $this->step = $this->session->get('step'); | |
| $this->attributes = $this->session->get('attributes'); | |
| } else { | |
| // Just being extra careful... | |
| $this->session->remove('attributes'); | |
| } | |
| return true; | |
| } | |
| /** | |
| * Clear session state and redirect to start of wizzard. | |
| */ | |
| public function startOver() | |
| { | |
| $this->session->remove('step'); | |
| $this->session->remove('attributes'); | |
| $this->redirect([static::$startRoute]); | |
| } | |
| /** | |
| * Create a form model and process it for the $current step of the wizzard. | |
| * | |
| * Redirect to $next on success, return form model with errors on validation error. | |
| * | |
| * @param string $current Scenario of current action | |
| * @param string|callable|bool $next Route to redirect to on success. If callable, it | |
| * takes the form model as argument and returns a (string) route, or it can redirect. | |
| * Set false to return the $form without redirecting. | |
| * | |
| * @return \yii\base\Model Form model with validation errors | |
| */ | |
| public function doForm($current, $next) | |
| { | |
| /** @var \yii\base\Model $form */ | |
| $form = new static::$formClass(['scenario' => $current]); | |
| if ($this->attributes !== null) { | |
| foreach ($this->attributes as $key => $value) { | |
| $form->$key = $value; | |
| } | |
| } | |
| $loaded = $form->load(Yii::$app->request->post()); | |
| if ($loaded && $form->validate()) { | |
| $this->session->set('attributes', $form->toArray()); | |
| $this->session->set('step', $current); | |
| if ($next !== false) { | |
| $this->redirect([is_callable($next) ? call_user_func($next, $form) : $next]); | |
| } | |
| } | |
| return $form; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment