Usando Mensagens Flash com Slim

Olá a todos,

Tenho usado o Slim Framework como framework principal nos meus trabalhos, e resolvi compartilhar como configurar o Slim/Flash no Twig usando o Slim.

Mensagens flash são informações que passamos via sessão do PHP, a diferença é que as bibliotecas de flash excluem o conteúdo logo após ser usado. Isso é útil para, por exemplo, mandar uma mensagem de erro no login do usuário, assim logo que a mensagem é mostrada para o cliente ela é destruída da sessão.

Estou usando um projeto minimo, por enquanto ele está assim:

Slim Miníno

Você pode ver o código aqui: https://github.com/GrupoToneladas/Blog-Slim-Flash. (Para ter acesso ao código nesse estado use a tag “inicio” desse repositório git checkout inicio).

Você pode testar o código com o servidor embutido do php com o comando: php -S 0.0.0.0:8001 -t public na pasta raiz do projeto.

Vamos começar adicionando a biblioteca de flash do Slim:

composer require slim/flash

Lembre-se de rodar o comando na pasta onde está o arquivo composer.json

Ok, após a instalação, vamos adicionar a biblioteca nas nossas dependências, faça isso no arquivo: app/config/dependencies.php

Adicione o seguinte trecho logo após o container ‘view’:

$container['flash'] = function () {
    return new \Slim\Flash\Messages();
};

Ficando assim:

<?php

$container = $app->getContainer();

$container['view'] = function ($container) {
    $settings = $container->get('settings')['view'];
    $view = new \Slim\Views\Twig($settings['template_path'], [
        'cache' => $settings['cache_path']
    ]);

    $view->addExtension(new \Slim\Views\TwigExtension(
        $container['router'],
        $container['request']->getUri()
    ));

    return $view;
};

$container['flash'] = function () {
    return new \slim\flash\messages();
};

# Actions
$container[App\Action\HomeAction::class] = function ($container) {
    return new App\Action\HomeAction($container->get('view'));
};

Adicione também no arquivo public/index.php a inicialização da sessão do php.

session_start();

Ficando assim:

<?php

session_start();

include __DIR__ . "/../vendor/autoload.php";
$settings = include __DIR__ . "/../app/config/settings.php";

$app = new \Slim\App($settings);

include __DIR__ . "/../app/config/dependencies.php";
include __DIR__ . "/../app/config/routes.php";

$app->run();

Agora para usar a biblioteca é só usar $this->flash->addMessage('identificador', 'mensagem');

O “identificador” é usado para adicionar/pegar as mensagens.

Vamos usar um exemplo, onde se o cliente tentar a página de admin sem estar logado ele vai ser redirecionado para a página inicial e vai mostrar a mensagem.

Adicione o seguinte trecho no arquivo app/config/routes.php

$app->get('/admin', function ($request, $response, $args) {
    $this->flash->addMessage('error', 'Você deve estar logado');

    return $response->withStatus(302)->withHeader('Location', '/');
})
->setName('admin');

Ficando assim:

<?php

$app->get('/', App\Action\HomeAction::class)
    ->setName('home');

$app->get('/admin', function ($request, $response, $args) {
    # Faça aqui a verificação se o usuário está logado
    $this->flash->addMessage('error', 'Você deve estar logado');

    return $response->withStatus(302)->withHeader('Location', '/');
})
->setName('admin');

Vamos adicionar as mensagens do flash como uma variavel global do twig, assim teremos essas mensagens disponiveis em qualquer trecho do sistema. Modifique o arquivo de dependências onde está o carregamento da view, adicionando o seguinte trecho antes do return da função:

    $env = $view->getEnvironment();
    $env->addGlobal('messages', $c->get('flash')->getMessages());
    $env->addGlobal('session', $_SESSION);

Ficando assim:

<?php

$container = $app->getContainer();

$container['view'] = function ($container) {
    $settings = $container->get('settings')['view'];
    $view = new \Slim\Views\Twig($settings['template_path'], [
        'cache' => $settings['cache_path']
    ]);

    $view->addExtension(new \Slim\Views\TwigExtension(
        $container['router'],
        $container['request']->getUri()
    ));

    $env = $view->getEnvironment();
    $env->addGlobal('messages', $container->get('flash')->getMessages());
    $env->addGlobal('session', $_SESSION);

    return $view;
};

$container['flash'] = function () {
    return new \Slim\Flash\Messages();
};

# Actions
$container[App\Action\HomeAction::class] = function ($container) {
    return new App\Action\HomeAction($container->get('view'));
};

Agora é só mostrar a mensagem no template home.html:

Insira esse trecho logo após o inicio da tag <body>:

      <!-- Aqui é onde usamos o identificador do addMessage() no nosso caso é o error -->
      {% for item in messages.error %}
        <div class="alert alert-danger">
            {{item}}
        </div>
      {% endfor %}

Ficando assim:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Slim Flash</title>

    <!-- Bootstrap -->
    <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
      <!-- Aqui é onde usamos o identificador do addMessage() no nosso caso é o error -->
      {% for item in messages.error %}
        <div class="alert alert-danger">
            {{item}}
        </div>
      {% endfor %}
    <h1>Usando o Slim Flash!</h1>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="/bootstrap/js/bootstrap.min.js"></script>
  </body>
</html>

Pronto, agora se você tentar acessar http://localhost:8001/admin você será redirecionado para a página inicial, e vai ver a mensagem, se você der F5 a mensagem desaparece.

No próximo post falarei sobre os middlewares do Slim.

comments powered by Disqus