Como usar o Form Validation com uma função de Callback
A biblioteca Form Validation do CodeIgniter é muito útil e simples de usar quando queremos validar no lado do servidor os campos de um formulário HTML.
O uso padrão que ela oferece já é de grande valia, porém, esta biblioteca tem uma funcionalidade muito interessante que nos permite chamar uma terceira função para verificar um campo.
Digamos que você não quer validar somente se um campo está vazio ou não, mas na verdade, precisa analisar o conteúdo do que foi postado e baseado nisso, mandar uma mensagem personalizada ao usuário.
Vamos tomar como exemplo o seguinte caso:
Você disponibiliza um formulário comum ao usuário porém com um campo de envio de arquivos que aceita somente imagens de no máximo 2MB.
Todos os campos são de preenchimento obrigatório, exceto o do arquivo.
Porém, caso o usuário decida enviar um arquivo, você precisará verificar se o que o usuário enviou é uma imagem e também o seu tamanho.
Ou seja, nas suas regras de validação, você não poderá colocar esta campo como obrigatório.
A solução é você indicar na regra de validação deste campo uma função de callback, ou seja, o CodeIgniter vai chamar um método que terá como função analisar o conteúdo do campo e a partir disto devolver uma resposta apropriada.
No post de hoje eu não vou mostrar uma aplicação completa, somente o trecho de código responsável por fazer tudo isto funcionar.
Digamos que você tem um controller com um método chamado store() que é responsável por receber os dados vindos do formulário.
Dentro deste médodo, existem as seguintes regras de validação, veja abaixo:
$this->load->library('form_validation'); $regras = array( array( 'field' => 'nome', 'label' => 'Nome', 'rules' => 'required' ), array( 'field' => 'email', 'label' => 'E-mail', 'rules' => 'required' ), array( 'field' => 'telefone', 'label' => 'Telefone', 'rules' => 'required' ), array( 'field' => 'descricao', 'label' => 'Descrição', 'rules' => 'required' ), array( 'field' => 'userfile', 'label' => 'Anexar Imagem', 'rules' => 'callback_verifica_tamanho_anexo' ), ); $this->form_validation->set_rules($regras); if ($this -> form_validation -> run() == FALSE) { $this -> load -> view('v_formulario'); } else { //salva no banco de dados. }
No código acima a novidade é o que consta na regra de validação do campo chamado userfile.
Repare que em “rules” eu chamo um método chamado verifica_tamanho_anexo que está dentro do próprio controller. Para você chamar um método basta você acrescentar o prefixo “callback_“, que quando a validação atingir este ponto, seu método será chamado.
O restante do código é o padrão da biblioteca form validation, ou seja, se o retorno da execução do método run() do form validation for igual a FALSE, indica que o formulário não foi validado, então chamo a view novamente, caso contrário, eu continuo e escrevo o restante do código que irá salvar os dados no banco, que não está sendo mostrado aqui.
Veja abaixo agora o método verifica_tamanho_anexo:
public function verifica_tamanho_anexo(){ $anexo = $_FILES['userfile']; if (empty($anexo['name'])) { return TRUE; } else { $config['upload_path'] = './uploads/'; $config['allowed_types'] = 'png|gif|jpg|jpeg'; $config['max_size'] = 2048; $this->load->library('upload', $config); if ( $this->upload->do_upload()) { return TRUE; } else { $this->form_validation->set_message('verifica_tamanho_anexo', $this->upload->display_errors()); return FALSE; } } }
Repare que nesta função eu uso uma outra biblioteca do CodeIgniter responsável pelo upload de arquivos chamada File Upload.
Todo o conteúdo de um envio de arquivo através de um formulário fica dentro da variável super global chamada $_FILES e ali dentro há um índice chamado ‘userfile‘ que corresponde ao nome do campo no formulário.
Este índice também é uma array e dentro dele existe um outro índice chamado ‘name‘ que me retorna o nome do arquivo enviado.
E é aqui que eu verifico se um arquivo foi ou não postado simplesmente através da função empty() do PHP.
Caso nada tenha sido postado, a verificação do IF irá retornar TRUE, e então eu saio da função com um simples return TRUE, que indicará ao Form Validation que o formulário poderá ser postado, já que o campo de anexo não é obrigatório.
Caso algum arquivo tenha sido enviado, então eu passo para a verificação do tamanho e formato do arquivo.
A biblioteca File Upload do CodeIgniter é bem simples de entender. Aqui basicamente eu configuro os parâmetros da biblioteca e também os formatos de arquivo permitido e seu tamanho máximo em kilobytes.
Caso o arquivo passe no teste de verificação eu simplesmente dou um return TRUE e saio da função, indicando ao Form Validation que o teste passou e que nesse caso há um arquivo em anexo.
Caso o arquivo não tenha passado no teste você poderá recuperar o erro através do método display_errors() da biblioteca Upload.
Neste caso o que eu faço é atribuir este erro ao campo de arquivo, e eu faço isso através desta linha:
$this->form_validation->set_message('verifica_tamanho_anexo', $this->upload->display_errors());
Aqui eu consigo vincular o tipo de erro ao campo que está sendo verificado através da passagem do nome da função como parâmetro, neste caso somente: verifica_tamanho_anexo.
Após isso eu dou um return FALSE que vai indicar ao Form Validation que a validação não foi bem sucedida, e assim a view é recarregada com a mensagem de erro em questão.
Lembre-se que as mensagens de erro por padrão estão em Inglês. Você pode baixar um pacote de tradução do CodeIgniter lá no github ou então traduzir por conta própria este arquivo: system/language/english/form_valdiation_lang.php.
E desta maneira você pode criar agora suas próprias funções de validação que trabalharão em conjunto com o Form Validation, estendendo, assim, sua funcionalidade.
Abraços
Fábio