terça-feira, 6 de novembro de 2012

Tô vendo tudo em dobro : Como utilizar dois ou mais banco de dados ao mesmo tempo com Zend

Muita gente tenta criar uma aplicação e se depara com o fato de ter de utilizar mais que um banco de dados ao mesmo tempo.

Uma situação típica : existe um aplicativo ( que não foi você quem fez ) que têm um banco de dados próprio e você não pode alterar os dados dele, somente ler.

Mas ao mesmo tempo você precisa usar esses dados para seu ERP feito em Zend, e não pode alterar o banco de dados do outro aplicativo, pois você precisa de um gerenciamento de usuários do seu ERP por exemplo.

Neste caso, você precisará criar um banco de dados próprio para seu ERP, e trabalhar junto com o banco de dados do outro aplicativo.

Então, vem a pergunta natural : como faço isso no Zend ? A resposta é surpreendentemente simples.


Para este post, considere dois banco de dados : 'db1' e 'db2'. O banco de dados 'db1' é do tipo 'dbtype1' ( onde 'dbtype1' pode ser o mysql, postgres, mssql, etc ) e o 'db2' seria do tipo 'dbtype2'.

No arquivo 'application/configs/application.ini' de seu projeto, configure esses banco de dados assim:


;; application/configs/application.ini

;; Configura o adaptador para 'db1' e o define como o adaptador padrão da aplicação.
resources.resourcealias.dbalias1.adapter  = pdo_dbtype1
resources.resourcealias.dbalias1.host     = host1
resources.resourcealias.dbalias1.username = userdb1
resources.resourcealias.dbalias1.password = passdb1
resources.resourcealias.dbalias1.dbname   = db1
resources.resourcealias.dbalias1.default  = true

;; Configura o adaptador para 'db2'.
resources.resourcealias.dbalias2.adapter  = pdo_dbtype2
resources.resourcealias.dbalias2.host     = host2
resources.resourcealias.dbalias2.username = userdb2
resources.resourcealias.dbalias2.password = passdb2
resources.resourcealias.dbalias2.dbname   = db2
resources.resourcealias.dbalias2.default  = false

Aqui devemos notar que 'resourcealias' é um apelido para esse recurso, 'dbalias1' e 'dbalias2' são apelidos para as conexões, 'pdo_dbtype1' e 'pdo_dbtype1' são os tipo de banco de dados, como 'pdo_mysql' para MySQL, 'pdo_pgsql' para PostgreSQL, etc. O resto é auto-explicativo, espero ...


Pois bem, definido a configuração dos bancos de dados, agora abramos o 'Bootstrap.php' e fazemos um 'inicializador':

public function _initDbRegistry(){

    $this->bootstrap('resourcealias');
    $obj = $this->getPluginResource('resourcealias');
    Zend_Registry::set('adapteralias1', $obj->getDb('dbalias1'));
    Zend_Registry::set('adapteralias2', $obj->getDb('dbalias2'));

}

E agora simplesmente, crie seu model e adicione:

class Meumodel1_Model extends Zend_Db_Table_Abstract {

    protected $_name    = 'uma_tabela_qualquer_do_db1';
    protected $_adapter = 'adapteralias1';

}

class Meumodel2 extends Zend_Db_Table_Abstract {

    protected $_name    = 'uma_tabela_qualquer_do_db2';
    protected $_adapter = 'adapteralias2';

}

E está pronto tudo o que você precisa para utilizar dois bancos de dados totalmente diferentes juntos. Definida a classe, você poderá criar os métodos e objetos de seus modelos como sempre utilizou com Zend, inclusive usando relacionamento de tabelas ( fiz um post sobre isso aqui ) sem problemas.

Eeeee até a próxima.




Referências




domingo, 19 de fevereiro de 2012

Bota uma branquinha ai :: Habilitando caracteres brancos no campo do formulário

sso é um probleminha que existe quando queremos habilitar um campo que pode ter um espaço em branco no formulário, como por exemplo, na hora de inscrever um usuário e é pro bendito colocar o nome inteiro dele. Nessa hora, o espaço entre os nomes têm um espaço em branco.

Pra ir bem rápido: você têm no seu form da aplicação Zend um validator


...

'validator' => array('Alpha')

...


Pois bem, para habilitar caracteres brancos no form, basta acrescentar


...

'validator' => array('Alpha', array('allowWhiteSpace' => true))

...

E pronto. Simples assim só mamão com açucar.

Até a próxima.



Referências:

- Standart Filter Class : http://framework.zend.com/manual/en/zend.filter.set.html


domingo, 12 de fevereiro de 2012

Essa é minha casa ? :: Sistema simples de login com Zend

Esse deve ser o que deixa boa parte dos programadores de Zend com água na boca.
Um sistema de login, é uma das maiores nescessidade quando se colocar seu apĺicativo online e não quer ver fulano mechendo na sua área administrativa que tanto tempo levou pra fazer. Ou quando cria um sistema em que seus usuários fazem coisas escondidas que só eles podem saber ... hehehe
De qualquer forma, um sistema de login é o que vão ter agora.
Primeiro, temo de criar a tabela de usuarios no banco de dados:

CREATE TABLE IF NOT EXISTS 'usuarios' (
  'id' int(11) NOT NULL AUTO_INCREMENT,
  'login' varchar(255) NOT NULL,
  'senha' varchar(255) NOT NULL
  PRIMARY KEY ('id')
);

Simples de entender né ?

A partir disso, entre no seu terminal, vá para a pasta de seu aplicativo em Zend, e criemos o formulario de login para colocar na página inicial ( controller index e action index ):

$ zf create form login

Abra o arquivo 'application/forms/Login.php' gerado, e coloque as linhas

class Application_Form_Login extends Zend_Form {

    public function init(){

        // Define a página do action, no caso, o proprio action index de login.
        setAction('index');
 
        // Método de envio do form.
        $this->setMethod('post');
         
        // Nome de usuário.
        $this->addElement('text', 'login', array( 'label'    => 'Login', 
                             'required' => 'true',            
               'validator' => array('noempty')  
                                                )
                         );
 
        // Senha de usuário.
        $this->addElement('password', 'senha', array( 'label'    => 'Senha',
                   'required' => 'true',
                   'validator' => array('noempty')
                                                    )
                         );
        
        // Botão de submissão.
        $this->addElement('submit', 'submit', array('label' => 'Entrar') );
     
    }

}


E agora, no seu controller 'controllers/IndexController.php' escreva as linhas no action 'indexAction'


public function indexAction(){
     
       // Cria o objeto de formulário.
     $loginForm = new Application_Form_Login();

     // É verificado se existem dados enviados via post ( caso de tentativa de login ).

     // Verifica se existem dados enviados via POST.
     if( $this->getRequest()->isPost()  ) {
        
                // Salva os dados enviados via post no array '$data'.
      $data = $this->getRequest()->getPost() ;
 
         // Verifica se os dados são válidos.
         if( $loginForm->isValid($data)  ) {

          // Pega o nome de usuário e a senha enviados pelo POST.
          $login = $loginForm->getValue('login');
                  $pass  = $loginForm->getValue('senha');
                  
             ///////////////////////////////////////////////////////////
             // Pega as informações do adaptador do banco de dados.
             $dbAdapter = Zend_Db_Table::getDefaultAdapter();
                          
             // Inicia o adaptador Zend_Auth para banco de dados.
                // É definido a tabela do db e os campos que serão usados
                // para comparar com os campos de login. 
             $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
             $authAdapter->setTableName('usuarios')
                     ->setIdentityColumn('login')
                    ->setCredentialColumn('senha')
                     ->setCredentialTreatment('MD5(?)');
                // Aqui, a senha é transformada num hash md5 e só então
                // comparado com a senha registrada no db ( que está em md5 também ).
                // Se você usa SHA1 ou outra codificação, é aqui que vocÊ deve declarar.
                //////////////////////////////////////////////////////////
                 
                ///////////////////////////////////////////////////////////
                // Agora, é comparado os dados digitados com os registrados.
             $authAdapter->setIdentity($login)->setCredential($pass);

                // Pega a instância atual do Zend_Auth.
                $auth = Zend_Auth::getInstance();
                
                // Pega o resultado da comparação dos dados enviados com os registrados.
                $result = $auth->authenticate($authAdapter);
                
                // Caso o resultado seja positivo, o login é efetuado.
                if( $result->isValid() ) {                
                                 
                 // Pega o nome do usuário.
                 $user = $authAdapter->getResultRowObject();
                 
                 // Salva o nome do usuário para uso na sessão.
                 $auth->getStorage()->write($user);
                 
                 // Redireciona para a primeira página após o login.
                 $this->_redirect("index/primeirapagina" );
              
                }
                // Caso não seja positivo ...
                else{
                 
                 // Caso o usuário não esteja registrado, é mostrado uma mensagem mostrando o fato.
                   $this->view->messages = "Não foi possível realizar o login.";
                   
                   // Reimprime o formulário com os dados já digitados.
                   $this->view->loginForm = $loginForm->populate($data);

                }
                ///////////////////////////////////////////////////////////
                                           
           }
           // Caso os dados não foram digitados corretamente, é reimprimido o formulário com os dados para correção.
           else $this->view->loginForm = $loginForm->populate($data);
              
     }
     // Imprime por default o formulário na entrada do site.
     else $this->view->loginForm = $loginForm;
     
}

E a partir desse ponto, você já têm um sistema de login funcional, brinque um pouco com ele para er se está tudo certo, porque agora vamos para a real utilidade de um sistema de login.

Pois bem, se você perceber, ainda pode navegar pelas páginas de sua aplicação Zend sem precisar realizar o login ( digite na url qualquer endereço dela para ver que entra numa boa ainda ).
E a não ser que você tenha um motivo especial para fazer um sistema de login que deixe tudo aberto, o que queremos é impedir o acesso a pessoas não logadas, não ?
Pois bem, a "tranca da porta" de nossa aplicação são essas duas linhas:

// Pega a instância atual do Zend_Auth.
$auth = Zend_Auth::getInstance();
        
// Verifica se o usuário está logado.
if( $auth->hasIdentity() ) { <faz alguma coisa> }

Nessas duas linhas, você verifica se o usuário está logado, se não está, geralmente você o envia para a página inicial, assim

// Pega a instância atual do Zend_Auth.
$auth = Zend_Auth::getInstance();
        
// Verifica se o usuário está logado.
if( $auth->hasIdentity() ) { <faz alguma coisa> }
else $this->_redirect('index/paginainicial');

Essas linhas você pode colocar no action 'init()' de seus controllers que quer restringir acesso - ou em algum action em particular, ou mesmo nas próprias views -  e já terá garantido a um pouco de segurança a sua aplicação.

É isso ai. Não, não acabou. Ainda falta uma coisinha.

Quando você se loga, sua identificação no aplicativo fica salvo na instância do Zend_Auth, e voltar para a página inicial simplesmente não resolve isso, o que pode ser perigoso, pois o usuario se loga, navega, sai, mas seu login continua lá para um outro safado sem vergonha usar brincar de graça na sua aplicação.

Para impedir isso é bem simples também. Criemos uma action no 'IndexController.php' com o nome de 'logoutAction'

$ zf create action logout

e acrescente as seguintes linhas

public function logoutAction(){
     
      // Apaga da instância do Zend Auth a identificação no sistema.
      Zend_Auth::getInstance()->clearIdentity();
    
      // Redireciona para a página inicial do site.
      $this->_helper->redirector('index');
        
}

E assim, no seu layout, crie um link escrito 'logout' que aponte para esse action


<?php
$logoutUrl = $this->view->url(array('controller'=>'index', 'action'=>'logout'), null, true);
            
// Imprime a mensagem de boas vindas com o nome do usuário e o link para logout.
print "<a href=".$logoutUrl.">Logout</a>";
?>

Assim, para sair, basta clicar no link 'logout', e a saida do usuário ficará limpa.

Agora é só se divertir montando seus aplicativos, que atgora terão a devida segurança e privacidade que nescessitam. Até a próxima.






Referências:

- Zend Auth : http://framework.zend.com/manual/en/zend.auth.introduction.html

- Autenticação com Zend Framework : http://fernandomantoan.com/frameworks/zend-framework/autenticacao-com-zend-framework/

terça-feira, 7 de fevereiro de 2012

Vai no chute mesmo :: Como usar o baseUrl no Bootstrap

Bom, quem já programa em Zend a um tempinho, já sabe que para usar coisas como css , javascript , etc se faz , no modo Zend de ser, no Bootstrap.


Problema que, para fazer isso, ou você usar o caminho até esses arquivos de modo explícito ( colocando o caminho inteiro na mão ), ou vai se embolar com outros modos de tentar chamar o método 'baseUrl()' do Views  Helper.

Mas, para sua sorte, encontrei um jeito de fazer isso de forma rápida e limpa - ainda que exótica - de ter a baseUrl em uma linha só.

No seu 'Bootstrap.php', você pode colocar em qualquer método a linha


 $baseUrl = substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php'));

E pronto ! Você terá sua baseUrl para usar onde quiser e na forma que desejar. Até a próxima.