Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing View, Template and Controller and Model is optional

I was too sleepy when I asked the question, so sorry for that, anyway to make things clear I prepared the question for 2 hours.

I'm trying to organize my code and decided to organize it mvc'ish(mvc-like), I don't know if I can follow all the principles, but I wanted to be at least close to that.

My application has a front-controller (dunno if my definition is right), so that all the http-request of my application will be passing through a single point, in my case the index.php in the root directory of my application.

Having said that I have set it up like that, you can imagine that I used .htaccess to direct all request to index.php.

I exploded the url and created an array out of it, $url[] like so. So whenever I access my app like this http://localhost/app/pagename it'll be accessing a controller (pagename_controller)

I did it like this :

$file = $controller_path . $page . '_controller.php';

if (file_exists($file)) {
    require $file;
    $class_name = ucfirst($page) . '_controller';
    $target = new $class_name();
}

also I wrap it up in a Container, the 'decorator pattern', for future use, validations maybe. like this :

$controller = new Wrap($target);
$controller->index();

I don't know if the use of $controller variable name is appropriate so please forgive me when it is all wrong.

I kinda think that I can setup my application like this :

  1. user sends a request, how? by using the application means that he/she sends out a http-request, that will load the initial state of the application

    credit : phparchitect design patterns

As you can see in the diagram of my desired application structure, I was able to do only the first part which is to direct the request to a single entry (index.php)

Now the problems are the initialization of other parts of the application.

As of this moment, I have 3 files that I want to setup, but I am confused on how.

index_controller, index_view, Template

class Index_controller {
    private $model;
    private $view;

    public function __construct(){
        // optional model -> $this->model = 'index' 
        $this->view = 'index'  // 
    }

    public function index(){
        $this->load->view($this->view)
    }
}

class Index_view {
    private $model;
    private $template;

    public function __construct(Model $model = null){
         $this->template = new Template('default');
    }

    public function view() {
         $this->template->assign('css', 'default_css'); // don't know if this is efficient
         // or $this->template->assign('header', 'default_header');
         // or $this->template->assign('sidebar', 'default_sidebar');
         // or $this->template->assign('footer', 'default_footer');
         // or any other things I want to use in the template
    }
}

class Template {

    public $data = array();
    private $tmpl;

    public function __construct($template) {
         $this->tmpl = $template . '_tmpl.php';
    }

    public function assign($name, $value){
        $this->data[$name] = $value;
    }

    // public function output
    // function that will explode the data array and render it out as a webpage
    // I'll create templates and
}

With that at hand, I want to know now how do I link those things together. At the moment I have a system folder that can contain classes, and I setup a autoloader for that folder.

I am thinking of creating a Controller class and View class that acts as the ActionFactory and ViewFactory as illustrated in the diagram, although I know that these are not their responsibilities.

I am thinking of this :

class Controller {

    protected $load;
    public function __construct() {
        $this->load = new View();
    }
}

class View {
    public function __construct() {
    // some things i don't know
    }

    public function view() {
    // some things i don't know
    }
}

What are your suggestions and comments in my setup. How can I initiate the triad?

like image 957
Joey Hipolito Avatar asked Dec 19 '12 02:12

Joey Hipolito


1 Answers

Well, let's not get stuck on your implementation details too much. You can go read about securing your framework at some other time. Let's deal with your question...

I actually created a framework that works along the lines you are trying to implement. I think what you are missing is a RoutingHandler class. Routing is the physical manipulation of the URL, which tells your application which Controller to load, and which Action to run.

In my world I also have Modules, so the basic routing scheme is

Module -> Controller -> Action

These three items map to my URI scheme in that fashion. Variables can be appended also like so...

http://www.domain.com/module/controller/action/var1/val1/var2/val2

So, what happens after the URI is parsed, and control is passed over to the appropriate controller and action? Let's make some code up to demonstrate a simple example...

<?php    
    class indexController extends Controller {

        protected function Initialize() {
            $this->objHomeModel = new HomeModel;

            $this->objHeader = new Header();
            $this->objFooter = new Footer();

            $this->objHeader
                ->SetPageId('home');
        }

        public function indexAction() {
            $this->objHeader->SetPageTitle('This is my page title.');
        }
    }
?>

In the Initialize method, I'm setting some controller-wide stuff, and grabbing an instance of my Model to use later. The real meat is in the indexAction method. This is where you would set up stuff to use in your View. For example...

public function randomAction() {
    $this->_CONTROL->Append($intSomeVar, 42);
}

_CONTROL is an array of values that I manipulate and pass onto the View. The Controller class knows how to find the right template for the View because it is named after the Action (and in a sibling directory).

The Controller parent class takes the name of the action method and parses it like so...

indexAction -> index.tpl.php

You can also do some other fun stuff here, for example...

Application::SetNoRender();

...would tell the Controller not to render inside a template, but just complete the method. This is useful for those situations where you don't actually want to output anything.

Lastly, all of the controllers, models, and views live inside their own directory like so...

my_module
    controllers
        indexController.class.php
        someotherController.class.php
        :
        :
    models
        HomeModel.class.php
        :
        :
    templates
        index.tpl.php
        someother.tpl.php
        :
        :

I could go on, but I'm writing this from memory, and there are some wrinkles here and there, but hopefully this gives you food for thought.

like image 82
Ian Atkin Avatar answered Nov 14 '22 06:11

Ian Atkin