2. Controllers e Views

Controladores e Views

O que são controladores?

Se você não está acostumado com a arquitetura MVC, procure [[estudar o assunto|https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller]] para entender do que se trata em teoria e como o mundo da programação de softwares costuma empregá-lo.

Como nós empregamos os controladores:

Na prática, pensamos em um controlador como um local específico (classe) de seu aplicativo que realiza uma determinada tarefa através de ações (métodos). Ele controla o fluxo de dados recebidos pelo usuário do navegador e o destino desses dados. É ele inclusive que transfere as informações que poderão ser utilizadas nas views. Se você não está habituado com MVC a princípio pode parecer um pouco complexo e que isso tudo envolve muitas dificuldades lógicas, mas a verdade é que na prática acaba sendo bem simples.

Exemplo:

Vamos supor que você tenha em sua view um botão onde ao clicar ele recarrega a mesma página, mas disparando uma mensagem.

  1. O controlador pega esta requisição que pode ser identificada de vários métodos, mas vamos tratar aqui como POST.
  2. O controlador chama o método $this->addMsg("Eu sou uma mensagem", \SuitUp\Enum\MsgType::INFO) que vai adicionar a mensagem à variável $layoutMessages que pode ser recuperada no layout.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php
// Arquivo: ModuleDefault/Controllers/IndexController.php

namespace ModuleDefault\Controllers;

class IndexController extends AbstractController
{
    // Esta ação será executada ao acessar
    // http://seusite.dev/
    public function indexAction()
    {
        if ($this->isPost()) {
            $this->addMsg("Eu sou uma mensagem", \SuitUp\Enum\MsgType::INFO);
        }
    }
}

Perceba que o papel do controlador é receber a requisição feita pelo usuário e responder a ela de acordo com a necessidade.

Como criar um controlador

Agora que você já sabe o que é um Controlador vamos entender qual a estrutura básica para criar um novo.

  1. Defina o nome que quer dar ao seu Controlador (vamos dizer que seja usuário);
  2. Não esqueça que este nome será usado na URL, neste caso http://seusite.dev/usuario/index ou simplesmente http://seusite.dev/usuario
  3. Sem acentos ou espaços em branco, o nome do controlador deve iniciar com letra maiúscula seguido de minúsculas;
  4. Neste nosso exemplo o controlador usuário ficará UsuarioController;
  5. Este nosso controlador deverá ficar dentro da pasta Controllers do módulo escolhido;
  6. O nome da classe e do arquivo devem ser iguais, neste nosso caso, ModuleDefault/Controllers/UsuarioController.php

O arquivo deverá ter o seguinte conteúdo mínimo:

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

namespace ModuleDefault\Controllers;

class UsuarioController extends AbstractController
{
    public function indexAction()
    {
        // Seu conteúdo aqui

        // Para transferir um conteúdo para a view
        $this->addViewVar(array(
            'nomeDaVariavel' => 'Seu conteúdo'
        ));
    }
}

Note que para transferir uma variável para a view basta você utilizar o método $this->addViewVar();.

AbstractController

Você deve ter notado nos exemplos acima que os controladores costumam herdar de AbstractController e talvez pense que este arquivo é fornecido por nosso framework, mas isso não é verdade. A verdade é que este arquivo deverá ser criado por você dentro de cada módulo e nós sugerimos que isso seja feito para facilitar sua vida.

O AbstractController deve existir para que você possa personalizar alguns métodos que o SuitUp não implementou exatamente de acordo com o que você precisa para este projeto ou até mesmo para adicionar métodos que poderão ser compartilhados entre todos os controladores do módulo e assim melhorar a reusabilidade do seu código. Por isso dizemos que para uma boa aplicação o AbstractController é obrigatório! Mesmo que não seja de fato obrigatório que este arquivo exista.

Nós já mencionamos isso acima, mas talvez durante a leitura este bloco lhe tenha passado sem muita importância, por isso vamos frisar novamente: Deve existir um AbstractController para cada módulo do seu aplicativo. Isso evita edição de métodos que impactam em vários módulos ao mesmo tempo.

A ideia é criar neste arquivo métodos que são úteis para serem usados em diversos locais (do mesmo módulo) de seu sistema para além de aumentar a produtividade também não ter que reescrever o mesmo bloco de código várias vezes.
A estrutura mínima de um AbstractController deve ser:

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

namespace ModuleDefault\Controllers;

abstract class AbstractController extends \SuitUp\Mvc\MvcAbstractController
{
    // Adicione aqui os métodos que serão úteis a você em diversos controladores.
}

Você pode abrir o arquivo MvcAbstractController.php ou usar a função get_class_methods($this) para ver quais métodos já estão inclusos na instância.

Antes de sobrescrever algum método leia [[este link|2.1 MvcAbstractController]] para entender o workflow do SuitUp e evitar algumas dores de cabeça.

O que são views?

Nem só de PHP vive um site, obviamente será necessário mostrar conteúdos para o usuário e isso será feito através de HTML (com exceção aos WebServices que retornam preferencialmente JSON). O SuitUp relaciona cada método de um controlador a um arquivo .phtml automaticamente. Como ele faz isso? Cada módulo deve ter uma pasta chamada views e dentro dela uma pasta para cada controlador que por sua vez vai conter um arquivo para cada método do controlador. Nós vamos explicar um pouco melhor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
modules
|  ModuleDefault
|  ModuleAdmin
|  |  Controllers
|  |  |  AbstractController.php
|  |  |  UsuarioController.php
|  |  views
|  |  |  usuario
|  |  |  |  index.phtml
|  |  |  |  editar.phtml
|  |  |  layout.phtml
.htaccess
composer.json
index.php

Lembra do nosso controlador usuário?

 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
// Arquivo: ModuleAdmin/Controllers/UsuarioController.php

namespace ModuleAdmin\Controllers;

class UsuarioController extends AbstractController
{
    /**
     * Este método deve ser acessado por 'http://seusite.dev/admin/usuario'
     */
    public function indexAction()
    {
        // Seu conteúdo aqui

        // Para transferir um conteúdo para a view
        $this->addViewVar(array(
            'nomeDaVariavel' => 'Seu conteúdo'
        ));
    }

    /**
     * Este método deve ser acessado por 'http://seusite.dev/admin/usuario/editar'
     */
    public function editarAction()
    {
        // Este método deve editar um usuario
    }
}

Notou alguma coisa diferente? Agora o módulo usado é Admin, isso faz com que a URL mude também. Cada método deste terá um arquivo .phtml correspondente e serão eles: ModuleAdmin/views/usuario/index.phtml
ModuleAdmin/views/usuario/editar.phtml

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

        <!-- Note que esta variável foi enviada pelo controlador -->
        <?php echo $nomeDaVariavel; ?>

    </div>
</div>

Note que é possível dentro da view recuperar a variável $nomeDaVariavel que foi transferida do controlador através do método $this->addViewVar();

Talvez você tenha percebido que este arquivo, mesmo sendo HTML, não inicia de modo tradicional, ou seja, <!DOCTYPE html>. Isso porquê os arquivos de view contém apenas o conteúdo específico para eles e tudo aquilo que será repetido em todas as páginas do seu site ficam separados em um único arquivo chamado [[layout. Clique aqui para continuar|3. Layouts]].