wiki:ModelViewController

Introduction

The Model-View-Controller or MVC pattern is a well established pattern in web development that demands separation of the data models, controller logic, and actual html view. There is more general information about  MVC on wikipedia. This page is about how info-arena uses the model-view-controller pattern (in the simplest possible way).

Model

Broadly speaking, "models" are things (usually class instances) that represent logical entities in an application. For instance, you could code a "User" class to manage users inside an app. It usually happens that "models" interact with a database, that is they store and retrieve stuff to and from a database.

Because we strive to keep things simple, our "models" are nothing more than PHP hashes with string fields. Additionally, database interaction is done with PHP global functions. Consider the following example:

$user = user_get_by_username('wickedman');
if ($user) {
    echo "username : {$user['username']}\n";
    echo "full name: {$user['full_name']}\n";
    echo "email    : {$user['email']}\n";
}
else {
    echo "No such username\n";
}

That's all you need to access user information for a given username.

Now, here's how you update user information:

$new_values = array(
    "full_name" => "Chuck Norris",
    "password" => "fara numar"
);
user_update($new_values, $user['id']);

All functions that query the database directly are thrown into the same module (currently, common/db.php. You do should never do SQL queries outside that file.

View

In MVC jargon, the "view" is responsible with generating/rendering/displaying user interface. Every content page that you can see inside your browser, every web form that you fill is a "view". In general you should never print anything in php outside for a view.

In a web application most of the times a view is a "template". Think of templates as static HTML files with some placeholders that get replaced with actual informations. Info-arena doesn't use any template language; instead we use PHP itself.

The controller is responsible for building a large $view hash which is the forwarded to a view. Views are implemented as simple php code chunks in the www/views directory. All they get from the outside is the $view array (we do some black magic to ensure that).

Standard $View variables

The contents of the $view array depend on an informal "contract" of sorts between a view and a controller (actually, the relation doesn't have to be one-to-one). This can get rather messy, so we define some standard $view variables:

  • title: is the page title, the one displayed in the title bar.
  • form_values, form_errors: are used to implement forms. These two arrays are indexed by the same strings; a missing form_error means that the value is valid.

Proposed:

  • url_args, to construct the current url?

Sample View

<?php
    include('header.php');
?>
<form action="<?= getattr($view, 'action') ?>" method="post" class="login">
<ul class="form">
    <li>
        <label for="form_username">Utilizator (nume cont)</label>
        <input type="text" name="username" id="form_username" value="<?= fval('username') ?>" />
    </li>
    
    <li>
        <label for="form_password">Parola</label>
        <input type="password" name="password" id="form_password" value="<?= fval('password') ?>" />
    </li>
    
    <li>
        <input type="submit" value="Autentificare" id="form_submit" class="button important" />
        <a href="<?= url("reset_pass") ?>">Am uitat parola</a>
    </li>
</ul>
</form>

<?php
    include('footer.php');
?>

The code looks rather ugly but this is not really a problem. All this code does is print some things to standard output, and the uglyness is well isolated. All smart code is in nice clean php files.

Controller

All HTTP requests are handled through a single file (index.php). In that file the url is parsed and control is passed to a controller function, somewhere in the www/controllers directory. These functions most of the www-accessible bussines logic. They are responsible for building a $view array and passing it to a view.

Read all about the infoarena url scheme. FIXME: write more about controllers?