Yii – começando nossa aplicação

Oba! Finalmente! Até que enfim! Vamos começar a fazer nosso site/aplicação baseado no Yii Framework. O site de exemplo que iremos criar será simples (basicamente um cadastro de clientes), mas que nos dará uma boa noção do poder e facilidade do Yii.

Vamos começar pelo banco de dados. Iremos utilizar o MySQL, embora o Yii também trabalhe com outros bancos. Neste projeto iremos utilizar somente duas tabelas: uma para os usuários / admins do sistema e outra para os clientes. Se ainda não criou um banco de dados para a aplicação, crie-o, utilizando sua ferramenta preferida. Eu gosto de usar o HeidiSQL(http://www.heidisql.com/ -infelizmente ele está disponível somente para Windows, mas segundo o autor ele funciona no Linux, através do Wine).
Dê o nome que quiser para seu banco de dados. Eu coloquei o nome de “primeiraapp”.

Crie então as tabelas, seguindo as estruturas abaixo:

Tabela: usuarios

Nome do campo Tipo Tamanho Permitir NULL Valor padrão Chave Primária
id TINYINT 4 N AUTO_INCREMENT S
nome VARCHAR 50 N        
email VARCHAR 50 N        
senha VARCHAR 32 N        
admin TINYINT 1 N 0   

Tabela: clientes

Nome do campo Tipo Tamanho Permitir NULL Valor padrão Chave Primária
id INT 10    N AUTO_INCREMENT S
nome VARCHAR 50 N
email VARCHAR 50 N       
empresa VARCHAR 50 S      
telefone VARCHAR 10 S          
celular VARCHAR 11 S           

Tabelas criadas, você pode deixar a tabela de clientes vazia. Mas insira 2 registros na tabela de usuarios:

Registro 1
id:  1
nome:  Admin
email: coloque seu e-mail
senha: 21232f297a57a5a743894a0e4a801fc3
admin: 1

Registro 2
id: 2
nome:  usuario
email: usuario@teste
senha: f8032d5cae3de20fcec887f395ec9a6a
admin: 0

Lembre-se: na hora de logar, o nome do usuário será o e-mail cadastrado, a senha do admin é “admin” (sem aspas). A do usuário é “usuario” (também sem aspas). Apenas foi aplicado MD5 em ambas. Sugiro que em seus projetos você sempre utilize algum tipo de criptografia / hash para tratar as senhas.

Configurando a aplicação

Agora, abra o arquivo protected/config/main.php que foi criado pelo yiic dentro da pasta do projeto.
Localize, dentro do arquivo, as linhas abaixo:

  <br>'db'=>array(<br><br>            'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db',<br><br>        ),<br>

Comente esse trecho, e acrescente esse, logo abaixo:

 <br>'db'=>array(<br><br>            'connectionString' => 'mysql:host=ip ou dominio do servidor mysql;dbname=nome do banco de dados',<br><br>            'emulatePrepare' => true,<br><br>            'username' => 'login do mysql',<br><br>            'password' => 'senha do mysql',<br><br>            'charset' => 'utf8',<br><br>        ),

Substitua os dados do host, username e password. Com isso, vamos configurar nossa aplicação para utilizarmos o banco de dados criado no passo anterior, ao invés de utilizarmos o sqlite.

É através do arquivo protected/config/main.php que configuramos nossa aplicação. Definimos o nome do sistema, alguns dados “globais”, ativamos componentes etc.

Agora, faça um teste, acesse a app pelo navegador: http://localhost:8080/yii/primeiraapp. Repare que, aparentemente, nada mudou no site. Clique no menu login, e logue-se como admin/admin. Você continuará conseguindo se logar, pois o sistema de login criado pelo yiic não utiliza um banco de dados, mas sim uma classe onde dois nomes de usuários já estão pré-definidos.
 
 Vamos dar uma olhada nessa classe. Abra, em seu editor de textos/código, o arquivo /protected/components/UserIdentity.php.
Repare, na linha 8, que esse arquivo define uma classe de nome UserIdentity, que herda da classe CUserIdentity:

 <br>class UserIdentity extends CUserIdentity

 A classe CUserIdentity é utilizada para gerenciarmos o acesso e autenticação de usuários através de um login e de uma senha. Para mais detalhes sobre ela, veja: http://www.yiiframework.com/doc/api/1.1/CUserIdentity/

Continuando,  a classe estendida possui apenas um método, chamado “authenticate”:

 <br>public function authenticate()<br><br>    {<br><br>        $users=array(<br><br>            // username => password<br><br>            'demo'=>'demo',<br><br>            'admin'=>'admin',<br><br>        );<br><br>        if(!isset($users[$this->username]))<br><br>            $this->errorCode=self::ERROR_USERNAME_INVALID;<br><br>        elseif($users[$this->username]!==$this->password)<br><br>            $this->errorCode=self::ERROR_PASSWORD_INVALID;<br><br>        else<br><br>            $this->errorCode=self::ERROR_NONE;<br><br>        return !$this->errorCode;<br><br>    }

Como pode-se ver, a linha 20 define um array ($users), onde cada elemento do array define o login e a senha do usuário.
As linhas seguintes verificam se o login e senha digitado são válidos. Caso não sejam, geram códigos de erros referentes ao erro em questão.
A linha 31 é o retorno do método, ela retorna true caso o usuário tenha digitado um login e senha válidos, e false caso contrário.
Mas onde essa classe está sendo chamada? É o que veremos em breve.

SiteController

Como dito nos artigos anteriores, o Yii utiliza o padrão MVC. Quando você acessa a raiz da aplicação, o que o Yii faz é chamar o controller SiteController, que foi criado para nós. No Yii, os controllers tem essa nomenclatura: nomeController. Por exemplo, se você tem um controller “usuario”, o nome da classe será UsuarioController. O mesmo valeria, por exemplo, para “imoveis”, que ficaria “ImoveisController”.

Agora, faça um teste: acesse os endereços http://localhost:8080/yii/primeiraapp/http://localhost:8080/yii/primeiraapp/index.php?r=site/index. e http://localhost:8080/yii/primeiraapp/index.php?r=site.
Como você deve ter reparado, todos os acessos mostraram a mesma página. O que acontece é que, ao acessar a raiz do site (primeira url), o mecanismo do Yii chama o controller principal do site, que é o SiteController.

Na segunda url, é especificado o parâmetro “?r=site/index”, onde o r significa “route” (rota),  “site” é o nome do controller chamado e “index” é o nome do método que deve ser executado.  Na chamada, o  método é separado do nome do controller através da barra, ou seja, você chama o método com ?r=nomeDoController/metodoASerExecutado   Ao chamar por um controller, você não deve colocar o nome inteiro da classe. Em nosso exemplo, você não deve chamar por “?r=siteController”, mas apenas por “?r=site”.

Na terceira url somente o nome do controller é especificado, mas mesmo assim a action (que é como os métodos dos controllers são chamados) index também é executada. Se você digitar em uma url somente o nome do controller, o Yii irá procurar nele uma action chamada index. Caso ela exista, ele a executará. Caso contrário, ele gerará um erro 404. O mesmo erro será gerado se você tentar acessar um controller ou action inexistente.

Vamos dar uma olhada em algumas partes da classe SiteController. Abra o arquivo protected/controllers/SiteController.php.

A classe é declarada na linha 3:

class SiteController extends Controller<br>{<br>

Como pode ser notado, nossas classes controllers herdam de outra classe, chamada Controller. Essa não é uma classe do Yii, mas sim uma classe de nosso sistema, que foi criada para nós em protected/components/Controller.php. Esta, por sua vez, herda de uma classe CController (http://www.yiiframework.com/doc/api/1.1/CController/). Podemos personalizar a classe Controller, mas isso fica para outro momento. Voltemos à classe SiteController.

Como dito anteriormente, a action Index é a action/método padrão do site:

 /**<br>  * This is the default 'index' action that is invoked<br>  * when an action is not explicitly requested by users.<br>  */<br> public function actionIndex()<br> {<br>  // renders the view file 'protected/views/site/index.php'<br>  // using the default layout 'protected/views/layouts/main.php'<br>  $this->render('index');<br> }<br>

A action acionIndex tem somente uma linha de código (linha 32), onde é executado o método render. O método render é definido na classe mãe, CController (http://www.yiiframework.com/doc/api/1.1/CController#render-detail).
Ele serve, como o nome diz, para renderizar (ou “desenhar”) uma view. o parâmetro passado a ele é o nome da view, no caso, “index”. As views ficam localizadas em subpastas da pasta /protected/views/. As subpastas devem ter o mesmo nome do controller (embora views que estejam em outras pastas também possam ser chamadas).
No caso, como estamos trabalhando com o controller “site”, as views chamadas por ele ficam na subpasta /protected/views/site. Se você abrir o arquivo index.php que está dentro dessa pasta, verá que ele não tem tanto conteúdo assim. e que praticamente nenhum layout é especificado nele. O motivo é que o layout do site é definido através de templates, algo que veremos mais para a frente.

Tente alterar a view index.php, mas procure mudar somente as partes de texto, não altere o código caso não tenha certeza do que está fazendo. Após alterá-la, abra o site novamente, e veja que seu conteúdo foi alterado com o texto que você colocou.

Voltando às actions, para definir uma action em um controller você tem duas formas:
1 – criando um método, cujo nome deve ser actionMetodo. A nomenclatura é parecida com a dos controllers, mas aqui, a palavra “action” deve vir antes do nome do método. É o que foi feito com a action Index, vista mais acima.

2 – adicionando uma chamada ao array de retorno do método “actions”, que já existe em nossa classe:

 public function actions()<br> {<br>  return array(<br>   // captcha action renders the CAPTCHA image displayed on the contact page<br>   'captcha'=>array(<br>    'class'=>'CCaptchaAction',<br>    'backColor'=>0xFFFFFF,<br>   ),<br>   // page action renders "static" pages stored under 'protected/views/site/pages'<br>   // They can be accessed via: index.php?r=site/page&view=FileName<br>   'page'=>array(<br>    'class'=>'CViewAction',<br>   ),<br>  );<br> }<br>

Este método deve ser utilizado quando você quer que sua action chame alguma outra classe, ao invés de chamar um método de sua classe. Por exemplo, volte ao site e clique em “about”. Repare que a url de chamada é esta: ?r=site/page&view=about. Aqui estamos chamando a action “page” do controller site. o conteúdo após o “&” são os parâmetros que passamos para a action chamada. No caso, estamos indicando que o parâmetro “view” receba o valor “about”.
Dentro da função “actions”, vemos que, para a action “page”, é definida a classe CViewAction. Vendo a documentação da CViewAction (http://www.yiiframework.com/doc/api/1.1/CViewAction/), você encontrará um parâmetro chamado “view” (http://www.yiiframework.com/doc/api/1.1/CViewAction#view-detail). Esse parâmetro recebe o nome de uma view, semelhante à action index. Porém, as views aqui chamadas ficam armazenadas na subpasta “pages”. Essa pasta pode ser alterada (veja a documentação da classe CViewAction), e é usada para armazenar páginas “estáticas”, que não interajam com o sistema.

Acredito que ficou bastante claro o funcionamento dos controllers e actions no Yii. No próximo artigo iremos estudar e modificar a forma de funcionamento do login de nosso sistema. Mas enquanto isso, sugiro que dê uma olhada no código de nosso controller e também no código das views, para ir se familiarizando com o Yii.