Um controle
é uma instância de CController ou uma de suas classes derivadas.
Ele é criado pela aplicação durante a requisição do usuário. Quando um controle
entra em execução, ele também executa a ação requisitada, que, geralmente, recupera os modelos
necessários e exibe a visão apropriada. Uma ação
, em sua forma mais simples,
nada mais é do que um método na classe do controle, cujo nome começa com action
.
Um controle tem uma ação padrão. Quando a requisição do usuário não especifica qual
ação executar, a ação padrão será utilizada. Por padrão, essa ação é chamada index
.
Ela pode ser alterada através da propriedade CController::defaultAction.
Abaixo temos o código mínimo necessário para uma classe de controle. Uma vez que esse controle não define nenhuma ação, qualquer requisição feita para ele irá disparar uma exceção.
class SiteController extends CController
{
}
Controles e ações são identificados por seus IDs. O ID de um controle é representado
no formato caminho/para/xyz
, que corresponde ao arquivo de classe do controle em
protected/controllers/caminho/para/XyzController.php
, onde o xyz
deve ser
substituído pelos nomes dos controles (por exemplo, post
corresponde a
protected/controllers/PostController.php
). O ID de uma ação é o nome de seu método
sem o prefixo action
. Por exemplo, se um controle contém o método chamado
actionEdit
, o ID da ação correspondente será edit
.
Nota: Antes da versão 1.0.3, o formato do ID para os controles era
caminho.para.xyz
em vez decaminho/para/xyz
.
Usuários fazem requisições para uma ação e um controle em particular, por meio um rota.
Uma rota, é formada concatenando-se o ID de um controle e o ID de uma ação, separados
por uma barra. Por exemplo, a rota post/edit
refere-se ao controle PostController
e sua ação edit
. Por padrão, a URL http://hostname/index.php?r=post/edit
irá requisitar esse controle e essa ação.
Nota: Por padrão, as rotas fazem diferença entre maiúsculas e minúsculas. Desde a versão 1.0.1, é possível eliminar esse comportamento alterando o valor da propriedade CUrlManager::caseSensitive para false, na configuração da aplicação. Configurada dessa forma, tenha certeza de que você irá seguir a convenção de manter os nomes dos diretórios onde estão os controles e as chaves dos vetores em controller map e action map em letras minúsculas.
A partir da versão 1.0.3, uma aplicação pode conter módulos.
A rota para a ação de um controle dentro de um módulo deve estar no formato IDmodulo/IDcontrole/IDacao
.
Para mais detalhes, veja a seção sobre módulos.
Uma instância do controle é criada no momento em que a CWebApplication recebe um requisição do usuário. Dado o ID do controle, a aplicação irá utilizar as seguintes regras para determinar qual classe deve ser utilizada e onde ela está localizada:
Se a propriedade CWebApplication::catchAllRequest for especificada, o controle será criado com base nela, ignorando o ID do controle requisitado pelo usuário. Essa propriedade é utilizada principalmente para colocar a aplicação em modo de manutenção e exibir uma página estática de notificação.
Se o ID for encontrado em CWebApplication::controllerMap, a configuração do controle correspondente será utilizada para instanciar o controle.
Se o ID estiver no formato caminho/para/xyz
, será assumido que o nome da
classe é XyzController
e seu arquivo correspondente está em
protected/controllers/caminho/para/XyzController.php
. Por exemplo, o ID de controle
admin/user
será resolvido para a classe UserController
e seu arquivo correspondente
será protected/controllers/admin/UserController.php
. Se o arquivo não existir, um
erro 404 CHttpException será disparado.
Nos casos em que módulos são utilizados (a partir da versão 1.0.3), o processo acima é um pouco diferente. Nessa situação em particular, a aplicação irá verificar se o ID refere-se a um controle dentro de um módulo e, caso positivo, o módulo será instanciado, primeiro, seguido da instanciação do controle.
Como já mencionado, uma ação pode ser definida como um método cujo nome começa
com a palavra action
. De uma maneira mais avançada, podemos definir uma ação
como uma classe, e pedir para que o controle a instancie quando requisitada. Dessa
forma, as ações podem ser reutilizadas com facilidade.
Para definir uma ação como uma classe, faça como no exemplo a seguir:
class UpdateAction extends CAction
{
public function run()
{
// coloque a lógica aqui
}
}
Para que o controle tenha conhecimento dessa ação, devemos sobrescrever o método actions() na classe do controle:
class PostController extends CController
{
public function actions()
{
return array(
'edit'=>'application.controllers.post.UpdateAction',
);
}
}
No exemplo acima, utilizamos o path alias application.controllers.post.UpdateAction
para especificar que a classe de ação está em protected/controllers/post/UpdateAction.php
.
Trabalhando com ações baseadas em classes, podemos organizar nossa aplicação de forma modular. Por exemplo, a estrutura de diretórios a seguir pode ser utilizada para organizar o código para os controles:
protected/ controllers/ PostController.php UserController.php post/ CreateAction.php ReadAction.php UpdateAction.php user/ CreateAction.php ListAction.php ProfileAction.php UpdateAction.php
Um filtro é uma porção de código, configurada para ser executada antes e/ou depois que uma ação de um controle. Por exemplo, o filtro de controle de acesso deve ser utilizado para assegurar que o usuário está autenticado, antes de executar a ação requisitada; um filtro de desempenho pode ser utilizado para medir o tempo gasto para a execução de uma ação.
Uma ação pode ter vários filtros. Os filtros são executados na ordem em que aparecem na lista de filtros. Um filtro pode prevenir a execução da ação e dos demais filtros ainda não executados.
Um filtro pode ser definido como um método na classe do controle. O nome desse
método deve começar como filter
. Por exemplo, o método filterAccessControl
define
um filtro chamado accessControl
. O método do filtro deve ter a seguinte assinatura:
public function filterAccessControl($filterChain)
{
// utilize $filterChain->run() para continuar o processo de filtragem e executar a ação
}
Acima, $filterChain
é uma instância da classe CFilterChain, que representa a lista
de filtros associados com a ação requisitada. Dentro do método do filtro, podemos
utilizar $filterChain->run()
para continuar o processo de filtragem e executar a
ação.
Um filtro também pode ser uma instância de CFilter, ou de uma de suas classes derivadas. No código abaixo, vemos como definir um filtro como uma classe:
class PerformanceFilter extends CFilter
{
protected function preFilter($filterChain)
{
// lógica que será executada antes da ação
return true; // deve retornar false caso a ação não deva ser executada
}
protected function postFilter($filterChain)
{
// lógica que será executada depois da ação
}
}
Para aplicar os filtros às ações, precisamos sobrescrever o método
CController::filters()
. Esse método deve retornar um vetor com as configurações
dos filtros. Por exemplo:
class PostController extends CController
{
......
public function filters()
{
return array(
'postOnly + edit, create',
array(
'application.filters.PerformanceFilter - edit, create',
'unit'=>'second',
),
);
}
}
No código acima, especificamos dois filtros: postOnly
e PerformanceFilter
.
O filtro postOnly
é baseado em um método (o método correspondente já está
definido na classe CController); enquanto o filtro PerformanceFiler
é baseado
em uma classe. O alias application.filters.PerformanceFilter
especifíca que a
classe desse filtro está em protected/filters/PerformanceFilter
. Utilizamos um
vetor para configurar o filtro PerformanceFilter
, assim podemos inicializar devidamente
os valores de suas propriedades. Nesse caso, a propriedade unit
dessa classe
será inicializada com o valor second
.
Utilizando-se os operadores +
e -
, podemos especificar a quais ações os filtros
devem ou não ser aplicados. No último exemplo, o filtro postOnly
deverá ser aplicado
as ações edit
e create
, enquanto o PerformanceFilter
deve ser aplicado a
todas as ações, EXCETO nas ações edit
e create
. Caso nenhum desses operadores
seja especificado o filtro será aplicado a todas as ações.
Signup or Login in order to comment.