Application Controller

Setup

The following files are needed for this exercise..

Motivation

In large applications, the decision of screens to present can be dependent on large amounts of conditional logic and code. Alternatively, Input controllers / commands can make some of these decisions, although many controllers would be needed for different screens leading to code duplication.

The Application Controller centralises the control of application, navigation and page flow by mapping requests to commands and commands to views.

UML Diagram

Application Controller Class UML diagram

Usage

Router.php


namespace commands;
use \base\Registry;
use \base\Request;
use \base\Response;
use \commands\Command;
use \commands\HomeCommand;
use \commands\ErrorCommand;

require_once 'Registry.php';
require_once 'Request.php';
require_once 'Response.php';
require_once 'Command.php';
require_once 'HomeCommand.php';
require_once 'ErrorCommand.php';

class Router
{
    //attributes
    static private $_baseCommand;
    static private $_defaultCommand;
    static private $_errorCommand;

    //constructor

    public function __construct()
    {
        if (isset(self::$_baseCommand) == false)
        {
            self::$_baseCommand = new ReflectionClass("Command"); //sets the $_baseCommand to the abstract Command class
            self::$_defaultCommand = new HomeCommand();
            self::$_errorCommand = new ErrorCommand();
        }
    }

    //methods

    public function GetCommand(Request $request)
    {
        //Read command through the Request object using the key
        $command = $request->GetRequest('cmd');

        $sep = DIRECTORY_SEPARATOR; // = /

        //check the command request isset, if not return the default command (index page)
        IF (isset($cmd) == false)
        {
            return clone self::$_defaultCommand;
        }

        //format command

        $command = str_replace(array('.', $sep),"", $command);

        //get the path of the command e.g. commands\\{}Command.php

        $filePath = "commands\\{$command}Command.php";

        // check if the class exists in the file

        $class = "{$command}Command";

        if(file_exists($filePath))
        {
            @require_once $filePath;

            if (class_exists($class))
            {
                //  if yes - create a new reflection class passing in the command class
                $reflectionClass = new ReflectionClass($class); //collects information about the class

                //check if it is a subclass of the base command class

                if ($reflectionClass->isSubclassOf(self::$_baseCommand))
                {
                    //if so create new Instance
                    return $reflectionClass->newInstance();
                }
                else
                {
                    //else
                    //return a 404command
                    $response = Registry::GetInstance()->GetResponse();
                    $response->SetResponse('Error', "{$command} Command does not exist");
                    return clone self::$_errorCommand;
                }

            }
        }

        $response = Registry::GetInstance()->GetResponse();
        $response->SetResponse('Error', "{$command} Command does not exist");
        return clone self::$_errorCommand;


    }
}

The Router class above uses the GetCommand() method to resolve the command.

The front controller uses the Application Controller to retrieve the appropriate command, see below:


$command = ApplicationController::GetCommand($request);

Implementation

namespace controllers;


use base\Request;
use base\Response;
use commands\Router;

class ApplicationController
{

    static private $_router;
    static private $_views;

    public function __construct()
    {

    }

    static public function Init()
    {
        self::$_router = new Router();
        self::LoadViews();
    }

    static private function LoadViews()
    {
        self::$_views = array();
    }

    public function GetCommand(Request $request)
    {

    }

    public function GetView(Response $response)
    {

    }

}

Complete the Application Controller class. To do this add the Error.html page to the $_views array.

Hints

Hint 1 (Click To View)

Hint 2 (click to View)

Hint 3 (click to View)