1
\$\begingroup\$

I'm looking to simplify controller logic where multiple validation steps will either result in redirecting the browser or re-rendering the current view.

Overall I'm looking to:

  • Avoid excessive nested if statements
  • Avoid multiple calls to Controller::redirect with the same arguments
  • Avoid using "return $this->render();"
  • Set view data that depends on the actions arguments (excludes using Controller::beforeRender)
  • Avoid generating/setting additional view data (ie dropdown list data) unless the view will render

The sample below is CakePHP 2 but I assume this idea could apply to versions 3 or 4 as well.

Are there any potential issues or downsides with the generic sample I've provided below?

<?php
class MyController extends Controller {
    public function my_action($id = null) {
        try {
            //test controller args
            if (!$id) {
                throw new RedirectException('Invalid id selected');
            }

            //form submitted
            if ($this->request->is('post')) {

                //check various things
                if (!$this->validationStep1()) {
                    throw new AlertException('Please check something for step 1');
                }

                if (!$this->validationStep2()) {
                    throw new AlertException('Please check something for step 2');
                }

                //situation where the validation may throw
                try {
                    $this->validateStep3MayThrowSomething();
                }
                catch (Exception $e) {
                    throw new AlertException('Please check something for step 3');
                }

                //more checks here

                if (!$this->Model->save()) {
                    throw new AlertException('Error saving');
                }

                //successful completed if we are here
                throw new RedirectException('Action completed successfully');
            }
        }
        catch (RedirectException $e) {
            if ($e->hasMessage()) {
                $this->alert($e->getMessage());
            }
            $this->redirect(array('action' => 'index'));
        }
        catch (AlertException $e) {
            $this->alert($e->getMessage());
        }

        //set any data needed to render this view
        $this->set('someData', $this->Model->getSomeData());
        $this->set('someSpecifcData', $this->Model->getDataById($id));

    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.