Search code examples
phprefactoringfront-controller

How to refactor long Front Controller?


I am using a Front Controller to send the user through a series of pages with questions. Pretty much everything must be dynamic as the pages, the questions, and everything else is set in the admin interface and stored in the database.

I am tracking the user's progress through the database by storing a unique identifier in the session and storing the current page the user is on in the database so I can figure out the next page to send them to.

The thing is, there are a lot of special cases to check for. Right now the controller is over 300 lines long and the code is poorly written and I'm the one who wrote it. Plus, I am going to need to add a lot more to this system in the upcoming weeks such as user-generated content and different pages to show depending on where the user is coming from.

I can see that this controller is going to become a big mess fast if I don't organize it well.

What are some good ways or ideas to refactor this?


Solution

  • Generally it's easier to use URLs to determine what you should send to the client. If your questions are submitted via a <form> you can return a redirect to the next question once you have saved the answer. For example if this was one of your questions:

    <form action="/questions/14" method="post">...
    

    This would submit to /questions/14 and once you have saved the answer you can redirect to question 15:

    header('Location: /questions/15');
    exit;
    

    Once you have URLs in place you can split up your front controller into parts that relate to each question. Then all you need is some routing:

    if(preg_match('/\/questions\/([0-9]+)/',$_SERVER['REQUEST_URI'],$matches) > 0) 
    {
        $question_num = (int)$matches[1];
        if(!in_array($question_num, $valid_questions)) {
            // return 404
        }
    
        $controller_name = 'Question_' . $question_num;
        return new $controller_name; 
    } 
    else // check for urls that aren't questions ...