2.1 MvcAbstractController

MvcAbstractController

During a system development is very common you need to realize the same task in a several different places, for example, check out if there was a POST. This is one of the reasons to MvcAbstractController must to exist, with it we can provide you a lot of methods that are useful like short cuts for this kind of repeated tasks in your system.

By this way, you can implement your own methods here just extending this class and pointing the controller to this your new that we recommand to call AbstractController. [[You can found more details here.|2. Controllers and Views#abstractcontroller]]

But unless it's static, these methods can't be accessed from views or models, actually it can't be accessed from anywhere outside the scope from controller, so for do it you must to create a file functions.php on the root of your project and implement your own functions that will be accessible from everywhere. That way you just have to do one include to this file in your index.php ([[like this|1. Install#indexphp]]).

SuitUp Workflow

There's no secrets, SuitUp knows your controller extends the class MvcAbstractController, this is required. Some methods from this class are needed to the perfect work of framework and still in a correct order. By this way it's possible to create some rotines in your system to specifics situations.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// With controller instance SuitUp will call
// these methods in that order.

// 1. Launched before init and current action
$this->mvc->controller->preDispatch();

// 2. init method
$this->mvc->controller->init();

// 3. Current action (depends on URL)
$this->mvc->controller->{$this->mvc->actionName}();

// 4. Launched after current action, before show content on screen
$this->mvc->controller->posDispatch();
You can override these methods as you wish, but in case of preDispatch and posDispatch don't forget to call the original method too, otherwise SuitUp won't work properly.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace ModuleDefault\Controllers;

abstract class AbstractController extends \SuitUp\Mvc\MvcAbstractController
{
    public function preDispatch() {
        // Here you can implement what God touch in your heart

        // But don't forget to call the original method
        // because of properly work of SuitUp
        parent::preDispatch();

        // Or you can implement here what God touch in your heart
    }

    public function posDispatch() {
        // Here you can implement what God touch in your heart

        // But don't forget to call the original method
        // because of properly work of SuitUp
        parent::posDispatch();

        // Or you can implement here what God touch in your heart
    }
}

What are default methods from SuitUp

The list below describes all of the methods which are default from MvcAbstractController and can be used inside everyone controller from your system.

preDispatch init indexAction errorAction
notFoundAction posDispatch getMsgNsp getModuleName
getControllerName getActionName getLayoutName setLayout
renderView addViewVar isViewVar getViewVar
getParams getParam isPost getPost
~setLogin~ isLogged getLogin updateLoginKey
addMsg uploadFile uploadFileImageBase64 getReferer
redirect ajax addSessionFilter getSessionFilter
removeSessionFilter clearSessionFilter

$this->preDispatch();

Launched before anything on the controller, executes internally some actions to the properly work of SuitUp. Must not to be override without to be called internally with parent::preDispatch();.

$this->init();

Launched after preDispatch(), but before current action. For now, this method do not execute any internal action on SuitUp, so you don't need to call it with parent::init(); when override, even being a good practice to prevent future conflicts with missmatch versions. :eyes:

$this->indexAction();

The index action is called when the name of current action is not specified on URL ex.: http://yoursite.dev/ which will call the module default, index controller and index action. This method was included on MvcAbstractController to prevent when a new controller do not implement this action. When overridden do not need to call parent::indexAction();.

$this->errorAction();

Always that SuitUp found on the way one Exception not treated, it dispatchs to the error window of [[ErrorController|2.2 ErrorController (en)]]. In this controller named ErrorController will be executed this action if it won't of the type 404 (Page not found).

Read more in: [[ErrorController|2.2 ErrorController (en)]]

$this->notFoundAction();

Always that SuitUp found on the way one Exception not treated, it dispatchs to the error window of [[ErrorController|2.2 ErrorController (en)]]. In this controller named ErrorController will be executed this action when SuitUp is not able to found module, controller, action or view file.

Read more in: [[ErrorController|2.2 ErrorController (en)]]

$this->posDispatch();

Launched after any controller action, executes internally some actions to the properly work of SuitUp. It must not to be overridden without to be called internally with parent::posDispatch();.

$this->getMsgNsp();

We don't wanna mixes messages dispatched in different modules on your system, so this method returns the namespace for the current module. But what about this messages?

A little while below you'll realize that exists a method $this->addMsg($msg, $type = MsgType::INFO, $withRedirect = false);, with parameter $withRedirect = true SuitUp will retain this message on the $_SESSION to show it only in the next page, normally used before a $this->redirect($to);.

$this->getModuleName();

Return the current module name.

Sample:
Module default (http://seusite.dev/), return: default
Module Admin (http://seusite.dev/admin), return: admin

$this->getControllerName();

Return the current controller name.

Sample:
http://seusite.dev/: Return index
http://seusite.dev/admin/user: Return user

$this->getActionName();

Return the current action name.

Sample:
http://seusite.dev/: Return index
http://seusite.dev/admin/user/edit: Return edit

$this->getLayoutName();

Return the layout name which is being used at the moment. [[Click here|3. Layouts (en)]] to understand better about what is a layout for SuitUp.

$this->setLayout($name, $path = null);

1
2
(string) $name; // Name to the new layout, this must be the name of the file without `.phtml`, so do not use spaces or any special chars
(string) $path; // Path to the new layout file

Is possible to change the layout in execution time, see the example below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Try to execute this code from your controller to see what happens
public function indexAction()
{
    // Echo the current layout name
    echo dump($this->getLayoutName());

    // Change layout
    $this->setLayout('error');

    // Echo the new current layout name
    dump("\n<br/>"$this->getLayoutName());
}

$this->renderView($renderViewName, $vars = array(), $renderViewPath = null);

1
2
3
(string) $renderViewName;  // Name of the file to be rendered
(array)  $vars;            // Variables that will be available to that file
(string) $renderViewPath;  // Path to this file

Render a view is a therm that means you wish capture a HTML file and it's contents, you can even inject variables on it. It's very commom when, for example you need to send an e-mail through HTML to your client with some data as an ordered.

$this->addViewVar($name, $value = null);

1
2
(string) | (array) $name; // Variable name which will be accessible on the view or an array with name => value
(mixed) $value;           // It will be the value of the previous parameter if it's not an array

After to do the actions you need in your controller you probably will need transfer some data to the view, this method make exactaly it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// File: Whatever controller file
public function indexAction()
{
    $something = ["a", 156, 0.5, 'c'];
    $other = "A value from your mind";

    // You can transfer this variable to the view that way.
    $this->addViewVar('thing', $something);

    // Or can transfer several variables at the end of action (method)
    $this->addViewVar(array(
        'thing' => $something,
        'otherStuff' => $other,
    ));
}
Automatically this values will be available on respective view file.

$this->isViewVar($name);

1
(string) $name; // Variable name which are you looking for

You can check if a variable already was transferred to the view using this method.

$this->getViewVar($name);

1
(string) $name; // Variable name which are you looking for

Even before view dispatch you can get the value from a variable using this method.

$this->getParams();

This method return all parameters indicated through URL (query string GET) with parameters defined on the [[routes|6. Routes]].

$this->getParam($name, $default = null);

1
2
(string) $name;    // Parameter name which are you looking for
(mixed)  $default; // Default value which will be returned if parameter does not exists

This method will return the parameter (URL or Route param) with the name indicated by $name parameter from method and $default otherwise.

$this->isPost();

This method is extremely simple, but just equal important. With it is possible to check out if there was a POST from a form or WebService. Returns just true or false.

$this->getPost($name = null, $default = null);

1
2
(string) $name;   // POST item name to get
(mixed) $default; // Value that will be returned if item does not exists

You can use this method to get all POST values or just a single one item just using or not the parameters.

~~$this->setLogin(array $data = array());~~

Still not implemented. You can create the login to your system direct in the variable $_SESSION as we'll show below.

The MvcAbstractController got the attribute $authNsp which works like namespace and allows you to override it to you create a different session for each module from your system. That means that even being just only one system you can sign in with different users in different modules at the same time.

Simple Login

1
2
3
4
5
6
    // File: Anyone Controller

    // Come on, this is just an example
    $loginData = $this->getPost();

    $_SESSION[parent::$authNsp] = $loginData;
Realize that in this case we just save user data from POST direct in the session.

Login with namespace by module

1
2
3
4
5
6
    // File: AbstractController from your module

    public function __construct() {
        // Just be creative to create a really cool namespace
        parent::$authNsp = "someCoolNamespace";
    }
Realize that we changed the namespace and with it done the login data for different modules will be independent each other. After that is enough follow previous step to save the login data on $_SESSION[parent::$authNsp].

$this->isLogged();

Return true if exists something in the current login namespace and false otherwise.

static $this->getLogin($key = null, $default = null)();

1
2
(string) $key;    // The index which you are looking for
(mixed) $default; // A default value in case of previous index does not exists

If $key parameter was not passed so this method will return all in this namespace session. When $key parameter exists this method will seek for this index return it, but if this index does not exists so this method will return $default value.

Something interesting to be noted in this method is that it can be accessed from everywhere, even from the views statically.

Sample:

1
<h2>Name: <?php echo \SuitUp\Mvc\MvcAbstractController::getLogin('name'); ?></h2>

static $this->updateLoginKey($key, $value);

1
2
(string) $key;  // An existing index to update its value
(mixed) $value; // The value

Updates an index of the session namespace to the module. If the index was not found this method does nothing.

Just like getLogin this method is static too and can be called from everywhere.

$this->addMsg($msg, $type = MsgType::INFO, $withRedirect = false);

1
2
3
(string) $msg;       // The message
(string) $type       // Type to the message
(bool) $withRedirect // You will make a redirect before dispatch this message?

This method add a message to be dispatched separated by type by the system. To capture this message just at the next page just make true third parameter $withRedirect.

Sorry, we have to talk about Bootstrap. Nowadays several sites on web are made with Bootstrap and it brings alerts that are colorized boxes to show messages to the users. By default Bootstrap uses 4 colors to this boxes (alert-success, alert-warning, alert-info and alert-danger). Because of this if you open [[this file from SuitUp|https://github.com/braghimsistemas/suitup-php/blob/master/src/Enum/MsgType.php]] you will see exactaly these four types of messages. We really like Bootstrap, it's just awesome!

You can create your own types of messages with no problems, but if you will make it we recommand that it's to be done using constants to prevent typewrite mistakes and useless bugs. It's a very good practice.

To know how to get these messages from the view and layout [[click here|3. Layouts#mensagens-de-layout]].

$this->uploadFile($file, $where, $exitFilename = null, array $allowedExt = array('jpeg', 'jpg', 'pdf', 'png', 'gif'));

1
2
3
4
(array) $file;          // Index from $_FILES
(string) $where;        // Path to where upload the file
(string) $exitFilename; // Name to give to the uploaded file
(array) $allowedExt;    // Allowed extensions list

This method make the upload of the files by HTML forms.

If you open composer.json file from SuitUp will see that there's a require verot/class.upload.php. We aren't trying to make SuitUp your only one way to do what you have to do with your application. Actually we stand up for the use of libraries which are easy to handle and make all the hard work so instead of make our own file upload module we recommand [[verot/class.upload.php|https://github.com/verot/class.upload.php]] which is open source and available for years doing even more than needed.

If you feel this method do not suply your need, feel free to override it on your AbstractController.

Warning.

This method trows an Exception in error cases, so don't forget to "cover" your code with a try, catch

$this->uploadFileImageBase64($file, $maxFilesize = 524288);

1
2
(array) $file;     // Index from $_FILES
(int) maxFilesize; // Maximum file size

It's possible to save an image not as a file, but as a kind of string using for that base64, you just need to use this method.

Warning.

This method trows an Exception in error cases, so don't forget to "cover" your code with a try, catch

$this->getReferer();

This method returns the URL user was before came to the current page. It is made through $_SERVER['HTTP_REFERER'].

$this->redirect($to);

1
(string) $to; // Location where you want to redirect

This method is simply a short cut to the header('Location: $to');

Use to call this method with a return, so the system will literaly stops after that.

1
2
3
4
public function indexAction()
{
    return $this->redirect('/');
}

$this->ajax(array $data);

1
(array) $data // The array data which will be parsed in a JSON "object"

It's very common instead HTML there is the need from some action to return a JSON, being for an AJAX or even to build a WebService module. For that just use this method at the end of action passing an array formated just like you want the JSON. This own method avoid any HTML show and dispatch the header("Content-Type: application/json; Charset=UTF-8") too.

Warning!

Anyone change of code after this method has no effect, it just make a literaly exit which does application really stops after dispatch JSON result.


SessionFilter

You probably already needed to use data from a form to filter a result list. To do this you can use GET which get parameters from URL or POST which get it from another protocol and it's more safe.

Firstly we like to crimp that in most cases to use GET it's a really a good idea because like that the filters can be shared, but there's cases which this can be dangerous or you just don't wanna make the URL ugly.

Whatever way, when you make filters by POST and use pagination at the same time the filter data will be lost after the first page, to prevent it we made the methods below which help you in a simple way to keep the filter data even with pagination case.

How it works?
Through an especific namespace for each action from your system the SuitUp separate these filter data and store it in the session ($_SESSION).

Functional workflow sample.

 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
29
30
31
32
33
34
35
36
37
38
39
40
<?php
// File: ModuleDefault/Controllers/IndexController.php

namespace ModuleDefault\Controllers;

class IndexController extends AbstractController
{
    public function indexAction()
    {
        // Check if there was a POST
        if ($this->isPost()) {

            // Check if was clicked on the button to clear the form
            // this is made with <button type="submit" name="clear">Clear</button> 
            if ($this->getPost('clear', false)) {
                $this->clearSessionFilter();
            } else {

                // Add or replace the filters from the unique
                // session to this action
                $this->addSessionFilter($this->getPost());

                // Redirect to the same page to prevent the form
                // resend data confirmation from browser
                return $this->redirect('/');
            }
        }

        $userBo = new ModuleDefault/Model/UserBusiness();

        // Makes the query to the list normally
        // THIS LIST USE TO BE PAGINATED
        $list = $userBo->getList($this->getSessionFilter());

        // On the view this list will be accessible by $usersList
        $this->addViewVar(array(
            'usersList' => $list,
        ));
    }
}

$this->addSessionFilter($name, $value = null);

1
2
(string | array) $name; // Add a list or an index to the session
(mixed) $value;         // When the first parameter is an INDEX, this is the value to it

Add or update one or more values to the items on the unique form filter data space for the current action.

$this->getSessionFilter();

Return all the data to the current session filter.

$this->removeSessionFilter($key = null);

1
(string) $key; // Index you want to remove

Remove some index data from the current session filter.

$this->clearSessionFilter();

Remove all the data to the current session filter.