Page 1 of 1

My Action controller and View classes need to be seperated..

Posted: Sun Apr 13, 2008 12:15 pm
by kilbad
I am still very new to PHP, and am creating a simple MVC front controller. Everything works, but I have an ActionController class that basically contains my MVC "View" functionality within the displayView() function. I want to split the following class into (1) an ActionController class and (2) View class. Will you show me how you would split this class into those? What subclasses would you include where? I guess this is an opinion/best practice question. I just want to make sure I am keeping my business and presentation logic separated.

Thanks for your help in advance!

Code: Select all

 
<?php
 
abstract class ActionController {
 
    //Declaring variables
    protected $name;
    protected $viewData = array();
    protected $content;
    
    private static $pageDir;
 
    //Setting the page directory, which is passed from the FrontController
    public static function setPageDir($pageDir){
        self::$pageDir = $pageDir;
    }
 
    public function setName($name) {
        $this->name = $name;
    }
 
    public function getName() {
        return $this->name;
    }
 
    //Placing a value in the $viewData array at the key position
    public function setVar($key, $value) {
        $this->viewData[$key] = $value;
    }
 
    //Returns a value from the $viewData array located at the key position
    public function getVar($key) {
        if (array_key_exists($key, $this->viewData)) {
            return $this->viewData[$key];
        }
    }
    
    /*
        Checking for actionMethod in the Actions class (example: doFrontpage() within home/HomeActions.php5)
        with the method_exists function and, if present, the actionMethod and displayView functions are
        executed.
    */
    
    public function dispatchAction($action) {
        $actionMethod = "do" . ucfirst($action);
        if (!method_exists($this, $actionMethod)) {
            throw new FrontControllerException("Action Method not found!");
        }
 
        $this->$actionMethod();
        $this->displayView($action);
    }
 
    public function displayView($action) {
        if (!is_file(self::$pageDir . "/" . $this->getName() . "/" . $action . "View.php5")) {
            throw new FrontControllerException("Action View not found!");
        }
 
        //This foreach function goes over all of the elements in $this->viewData array, creates
        //a variable for every value, and the name of the value (the variable name) is the key's value.
        foreach ($this->viewData as $key => $value) {
            $$key = $value;
        }
        
        //Setting content variable to the path of the action View file
        $this->content = self::$pageDir . "/" . $this->getName() . "/" . $action . "View.php5";
        
        //Including a template file within which the action View file is included
        require_once self::$pageDir . "/template.php5";
    }
 
    public function __set($key, $value)  {
        $this->setVar($key, $value);
    }
 
    public function __get($key) {
        return $this->getVar($key);
    }
}
 
?>
 

Re: My Action controller and View classes need to be seperated..

Posted: Tue Apr 15, 2008 2:00 pm
by blueyon
I thought I would do a repost since this thread is more appropriate

This is just a bit of an example.

Its not finished and the coding in the render method is a bit sloppy.

Code: Select all

 
<?php
class PageController {
    protected $registry;
    protected $id;
    protected $template; 
    protected $layout;
    protected $children = array();
    protected $data     = array();
    
    public function __construct($registry) {
        $this->registry = $registry;
    }
    
    public function __get($key) {
        return $this->registry->get($key);
    }
    
    public function __set($key, $value) {
        $this->registry->set($key, $value);
    }
    
    public function getId() {
        return $this->id;
    }
        
    public function assign($key, $value) {
        $this->data[$key] = $value;
    }
            
    protected function forward($class, $method, $args = array()) {
        return new Action($class, $method, $args);
    }
    
    protected function redirect($url) {
        header('Location: ' . $url);
        exit();
    }
 
    protected function render($option = array()) {
        foreach ($option as $key => $value) {
            $this->$key = $value;
        }
    
        foreach ($this->children as $child) {
            $obj = $this->create($child);
                
            $forward = $obj->execute();
            
            if ($forward) {
                return $forward;
            }
                
            $this->data[$child] = $obj->getOutput();
        }
        
        if ($this->template) {
            $this->output = $this->fetch($this->template);
        }
        
        if ($this->layout) {
            $obj = $this->create($this->layout);
            
            $obj->data[$this->id] = $this->output;
                
            $forward = $obj->execute();
                
            if ($forward) {
                return $forward;
            }               
        }
        
        $this->response->setOutput($this->output);
    }
 
    function fetch($filename) {
    
    }
    
    private function create($controller) {
        $file  = DIR_CONTROLLER . $controller . '.php';
        $class = 'Controller' . $controller;
        
        if (file_exists($file)) {
            include_once($file);
            
            return new $class($this->registry);
        } else {
            exit('Error: Could not load controller ' . $controller . '!');
        }
    }
 
    public function getOutput() {
        return $this->ouput;
    }
} 
?>
 

Re: My Action controller and View classes need to be seperated..

Posted: Tue Apr 15, 2008 2:14 pm
by blueyon
For the render engine you could do:

Code: Select all

 
if ($this->template) {
    $view = new View($this->engine, $this->template, $this->data);
 
    $this->output = $view->render();
}
 
A bit like a database Adaptor.