Atributos
1Apresentação
O Temma oferece atributos PHP opcionais para controlar o acesso a controladores e ações.
Esses atributos podem ser combinados, então você pode adicionar vários atributos diferentes (e às vezes o mesmo atributo várias vezes, com parâmetros diferentes) ao mesmo controlador ou ação.
Além disso, você pode criar seus próprios atributos para gerenciar o acesso a controladores e ações.
Atributos fornecidos pelo Temma
O Temma fornece vários atributos, cuja documentação está disponível na seção "Helpers":
- Auth: Para restringir o acesso a usuários autenticados.
- Check: Para validar dados de entrada (parâmetros de URL/GET/POST, payload, arquivos) e dados de saída.
- View: Para gerenciar as visões de controladores e ações.
- Template: Para definir o caminho do arquivo de template.
- Method: Para gerenciar os métodos HTTP autorizados.
- Referer: Para filtrar o acesso pelo REFERER HTTP.
- Redirect: Para redirecionar requisições automaticamente
2Escreva seus próprios atributos
Você pode criar seus próprios atributos para gerenciar o acesso a controladores e ações.
No Temma, os atributos são ativos: o framework reage à sua presença; ele executa os atributos,
fornece a eles uma API, e os próprios atributos controlam o comportamento do framework.
Em comparação com outros frameworks, isso torna o Temma mais simples. Novos atributos podem ser adicionados sem exigir nenhuma alteração no núcleo do framework.
2.1Princípio
Seus atributos devem estender a classe \Temma\Web\Attribute e só podem ser aplicados a controladores e ações.
Um atributo deve definir um construtor, que pode receber os parâmetros exigidos pelo atributo.
O construtor não deve executar nenhuma lógica e deve apenas armazenar os parâmetros recebidos.
O processamento real do atributo deve ser implementado em um método apply(),
que recebe como parâmetro um objeto que implementa a interface
Reflector,
indicando o contexto no qual o atributo é executado. Isso pode ser um
objeto ReflectionClass (no nível do controlador)
ou um objeto ReflectionMethod (no nível da ação).
Por meio da herança, seus atributos têm acesso a funcionalidades bastante semelhantes às disponíveis para os controladores:
-
Acesso a variáveis de template por meio da notação com colchetes.
Por exemplo: $this['var'] = 'value'; para definir uma variável, e $var = $this['var']; para ler o valor de uma variável. -
Acesso a fontes de dados na forma de propriedades diretas do objeto.
Por exemplo: $this->db para acessar um banco de dados chamado db. -
Métodos $this->_httpCode() e $this->_httpError()
para definir o código de retorno HTTP, ou o código de erro HTTP.
Métodos $this->_getHttpCode() e $this->_getHttpError() para recuperar o código HTTP definido anteriormente. - Métodos $this->_redirect() e $this->_redirect301() para definir comandos de redirecionamento.
- Métodos $this->_view() para definir a visão, $this->_template() para definir o template, e $this->_templatePrefix() para definir o prefixo do template.
Além disso, propriedades são usadas para acessar os objetos internos do Temma:
- $this->_loader: instância do componente de injeção de dependências.
- $this->_session: instância do objeto de gerenciamento de sessão.
- $this->_config: instância do objeto de acesso à configuração.
- $this->_request: instância do objeto de gerenciamento de requisição.
- $this->_response: instância do objeto de gerenciamento de resposta.
Todos esses elementos permitem manipular o fluxo de execução da mesma forma que os plugins.
2.2Fluxo de execução
Para modificar o fluxo de execução, um atributo deve lançar uma exceção específica:
- \Temma\Exceptions\FlowHalt: interrompe o fluxo de execução. Nenhum outro plugin ou controlador será executado, e o framework passa diretamente ao processamento da visão ou do redirecionamento.
- \Temma\Exceptions\FlowRestart: reinicia o processamento da fase atual (pré-plugins, controlador ou pós-plugins).
- \Temma\Exceptions\FlowReboot: reinicia toda a cadeia de processamento (pré-plugins + controlador + pós-plugins).
- \Temma\Exceptions\FlowQuit: interrompe a execução do framework. Nenhum outro plugin ou controlador será executado. A visão não será executada e as requisições de redirecionamento são ignoradas.
2.3Exemplo
Aqui está um exemplo de um atributo chamado MyLog, que grava em um arquivo pouco antes de um controlador ser instanciado ou de uma ação ser executada. O nome do objeto ou método é gravado, junto com o nome do arquivo e o número da linha.
<?php
use \Temma\Base\Log as TµLog;
/**
* Atributo usado para gravar em um log o fluxo de execução
* de controladores e ações.
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
class MyLog extends \Temma\Web\Attribute {
/**
* Construtor.
* @param string $message (opcional) Mensagem a ser adicionada à linha de log.
*/
public function __construct(private ?string $message=null) {
}
/**
* Execução do atributo.
* @param \Reflector $context Contexto de execução (classe ou método).
*/
public function apply(\Reflector $context) : void {
// recuperar as informações
$name = $context->getName();
$file = $context->getFileName();
$line = $context->getStartLine();
// determinar o tipo de contexto
if ($context instanceof \ReflectionClass) {
$type = 'Controller';
// $name já contém o nome completo da classe
} elseif ($context instanceof \ReflectionMethod) {
$type = 'Action';
// $name contém o nome do método; adicionar o nome da classe antes
$name = $context->getDeclaringClass()->getName() . '::' . $name;
} else {
return;
}
// montar a string do log
$logString = "[$type] $name ($file:$line)";
if ($this->message)
$logString .= ' : ' . $this->message;
// gravar no log
TµLog::l($logString);
}
}
- Linha 9 : o objeto é declarado como um atributo que pode ser aplicado a classes e métodos.
- Linha 10 : definição do objeto, que estende \Temma\Web\Attribute.
- Linha 15 : construtor do atributo, que recebe um parâmetro promovido a uma propriedade privada.
- Linha 22 : método de execução, que recebe o contexto de execução como parâmetro.
- Linhas 23 a 38 : obtenção das informações necessárias para montar a mensagem de log.
- Linhas 40 a 43 : construção da mensagem de log.
- Linha 46 : gravação da string usando o objeto \Temma\Base\Log.
E aqui está um exemplo de como esse atributo pode ser usado:
<?php
/** Controlador. */
#[MyLog]
class Article extends \Temma\Web\Controller {
/** Ação que exibe a lista de artigos. */
#[MyLog('Article list')]
public function list() {
// ...
}
/**
* Ação que exibe um artigo.
* @param int $id Identificador do artigo.
*/
#[MyLog('Display article')]
public function view(int $id) {
// ...
}
}
-
Linha 4 : o atributo MyLog é aplicado ao controlador.
Isso adicionará a seguinte linha ao log: [Controller] Article (Article.php:4) -
Linha 7 : o atributo é aplicado à ação list().
Isso adicionará a seguinte linha ao log: [Action] Article::list (Article.php:7) : Article list -
Linha 16 : o atributo é aplicado à ação view().
Isso adicionará a seguinte linha ao log: [Action] Article::view (Article.php:16) : Display article