2. Controllers and Views

Controllers and Views

What is controllers about?

If you aren't habituated with MVC architecture, [[try out to study it|https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller]] to figure out what about is MVC in theory and how software programming world use to do it.

How we use controllers:

We think about a controller as a place specifically designed from your application (class) that realize some kind of job through actions (methods). It controls the data flow received from browser user and the destiny of these data. It's that what transfers data which could be useful in the views. If you aren't habituated with MVC at this point it can seem a little complex and that this whole thing should involve too many logic difficulties, but the truth is that in practice it's very simple.

Example:

Let's suppose you have in your view a button that when you click over it will reload the same page, but dispatching a message.

  1. Controller get this request that can be identified by a lot of ways, but let's suppose it's POST.
  2. Controller request the method $this->addMsg("I'm a message", \SuitUp\Enum\MsgType::INFO). It will add a message to the $layoutMessages variable that can be recovered in the layout
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
// File: ModuleDefault/Controllers/IndexController.php

namespace ModuleDefault\Controllers;

class IndexController extends AbstractController
{
    // This action is executed when you access
    // http://yoursite.dev/
    public function indexAction()
    {
        if ($this->isPost()) {
            $this->addMsg("I'm a message", \SuitUp\Enum\MsgType::INFO);
        }
    }
}

Realize that the role of the controller is receive the request made by browser user and respond it according to the need.

How to create a Controller

For now you already know what is a Controller, let's understand what is the basic structure to create a new one.

  1. Define the name you want to give to your new Controller (let's say it will be user);
  2. Don't forget that this name will be used on the URL, in this case http://yoursite.dev/usuario/index or just http://yoursite.dev/usuario;
  3. Without any special characters, the name of the controller must begin with one CAPITAL letter followed by lowercase characters and the namespace Controller at the end;
  4. In our example the controller user will be UserController
  5. This our controller must be inserted in Controllers folder inside the module choosen.
  6. The name of the controller class and file must to be identical, in our case the name of the file will be ModuleDefault/Controllers/UserController.php

Below you will see the minimum required content to the controller file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
// File: ModuleDefault/Controllers/UserController.php

namespace ModuleDefault\Controllers;

class UserController extends AbstractController
{
    public function indexAction()
    {
        // put your content here

        // To send content to the view
        $this->addViewVar(array(
            'variableName' => 'The content'
        ));
    }
}

Realize that to send a variable to the view you just need to use the method $this->addViewVar();.

AbstractController

You must to realized in the examples above that the controllers usually to inherit from AbstractController class and may thougth this file is supplied by SuitUp framework, but it's no the truth. The truth is that this file must to be made by you inside each module and we sugest it should be made for turn your own life easier.

The AbstractController must to exist because with it you can personalize some methods which SuitUp have no done exactally in according as you need for this your project or even for you can add some methods which will be useful and shared with all controllers inside the module and with that making better reusability of your code. Because of this we say that for a good application the AbstractController is required! Even don't being totaly needed that this file must to exist.

We already mentioned this above, but maybe while reading this idea could have passed unnoticed, because of that we will say it again: Must to exist one AbstractController for each module in your application. It will prevents edition of methods which have impact in several modules at the same time.

The idea is to create on this file methods that will be useful to be used in several locales on your system (at the same module). It will increase the productivity and you will not rewrite the same block of code several times.
The minimum structure to create an AbstractController must to be:

1
2
3
4
5
6
7
8
9
<?php
// File: ModuleDefault/Controllers/AbstractController.php

namespace ModuleDefault\Controllers;

abstract class AbstractController extends \SuitUp\Mvc\MvcAbstractController
{
    // Add here how many methods God touch in your heart to make your life better. =)
}

You can open the file MvcAbstractController.php or use the function get_class_methods($this) to see which methods is already implemented in the instance.

Before rewrite some method read [[this link|2.1 MvcAbstractController]] to understand the workflow of SuitUp and avoid some headaches.

What are views?

Neither only from PHP a site lives, obviously will be needed show contents to the user and it will be made trough HTML (exception WebServices which return only preferably JSON). The SuitUp relates each method from a controller with a file .phtml automaticaly. How it can do that? Each module must to have a folder named views and inside it one folder for each controller which must to contain a file for each controller method. We will explain it a little better.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
modules
|  ModuleDefault
|  ModuleAdmin
|  |  Controllers
|  |  |  AbstractController.php
|  |  |  UserController.php
|  |  views
|  |  |  user
|  |  |  |  index.phtml
|  |  |  |  edit.phtml
|  |  |  layout.phtml
.htaccess
composer.json
index.php
Do you remember our controller user?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
// File: ModuleAdmin/Controllers/UserController.php

namespace ModuleAdmin\Controllers;

class UserController extends AbstractController
{
    /**
     * This method will be accessed by 'http://yoursite.dev/admin/user'
     */
    public function indexAction()
    {
        // Your content

        // Transfer content to the view
        $this->addViewVar(array(
            'yourVariable' => 'The content'
        ));
    }

    /**
     * This method will be accessed by 'http://seusite.dev/admin/user/edit'
     */
    public function editAction()
    {
        // Logic to edit user
    }
}

Did you noticed something different? Now the module used is Admin, it make URL change too. Each of these methods is related to one .phtml file that are:
ModuleAdmin/views/user/index.phtml
ModuleAdmin/views/user/edit.phtml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!-- File: ModuleAdmin/views/user/index.phtml -->
<div class="panel panel-primary">
    <div class="panel-heading"><i class="fa fa-bell"></i> Header</div>
    <div class="panel-body">

        <!-- Realize that this variable was sent by controller -->
        <?php echo $yourVariable; ?>

    </div>
</div>

Realize that is possible inside the view to use $yourVariable that was sent by controller through the method $this->addViewVar();

Maybe you have noticed that this file, even being HTML, does not begin with traditional type, I mean, <!DOCTYPE html>. This is because the view files contents are just the specific content for itself, everything that is repeated in all pages from your site used to be separated in only one file called [[layout. Click here to understand it better.|3. Layouts]].