Zend Framework + Upload+ ProgressBar


Neste post irei mostrar como fazer uma barra de progresso nos formulário que possuem upload. A teoria da operação é a seguinte: Utilizaremos dois actions “processAction” e “progressAction”. O 1° irá fazer o processamento do formulário (nada fora do normal até aqui :) . Mas a mágica acontece no action “progressAction” que envia para o browser como está o progresso do upload. Quando envia o formulário, um javascript faz requisições para “progressAction” via ajax e este retorna as informações necessárias para fazer a barra de progresso funcionar.
Para este tutorial, é necessário a extensão uploadprogress. Esta extensão que permite ao php recuperar o status do envio. Segue o link para o download da extensão:

A extensão precisa acessar a pasta de uploads temporária, portanto é necessário configurar no php.ini o caminho. Inclua as seguintes linhas no seu arquivo de configurações do php:


[UploadProgress]

extension=php_uploadprogress.dll
uploadprogress.file.contents_template="C:WINDOWSTempupload_contents_%s"
uploadprogress.file.filename_template="C:WINDOWSTempupt_%s.txt"

Obs: Reparem para a última parte dos caminhos que devem ser mantidos (“upload_contents_%s” e “upt_%s.tx”)

Obs2: Sei que não é a melhor opção, mas estou fazendo o tutorial baseado em ambiente Windows. Mas os passos são os mesmos para ambiente Unix.

Segue o controller que fará todo o controle do upload:


class IndexController extends Zend_Controller_Action
{
/**
* Monta o formulário
*
* @return void
*/
public function indexAction()
{
$request = $this->getRequest();
$this->view->id = md5(microtime() . rand());
}

/**
* Processo os arquivos quando forem finalizados
*
* @return void
*/
public function processAction()
{
Zend_Layout::getMvcInstance()->disableLayout();
$this->_helper->viewRenderer->setNoRender();

Zend_Debug::dump($_FILES);
Zend_Debug::dump($_POST);

}

/**
* Retorna o json com as informações do progresso do upload.
*
* @return void
*/
public function processInfoAction()
{
Zend_Layout::getMvcInstance()->disableLayout();
$this->_helper->viewRenderer->setNoRender();

$id = $this->_getParam('id');
echo Zend_Json::encode(uploadprogress_get_info($id));
}
}

indexAction apenas renderiza o formulário passando o ID do post. É por este ID que a extensão saberá identificar de qual upload deve ser retornado as informações.

processAction apenas recebe os arquivos e ecoa na tela as informações.

processInfoAction recebe o ID do upload e retorna o json necessário para o javascript fazer a barra de progresso.

Este é o HTML montado para o upload. Notem que é obrigatório o campo hidden com o identificador gerado no indexAction.


<form action="<?= $this->url(array('action'=>'process')) ?>" id="frmUpload" enctype="multipart/form-data" method="post">
<input type="hidden" name="UPLOAD_IDENTIFIER" value="<?= $this->id; ?>" id="UPLOAD_IDENTIFIER"/>

<label>Select File:</label>
<input type="file" name="file" style="display:block" />

<input type="submit" value="ok" />
</form>
<div id="uploadprogressbar"></div>

A div identificada por “uploadprogressbar” é onde o será feita a barra de progresso.

O que resta agora é somente o javascript. Para a barra de progresso é necessário o jQuery e o plugin jQuery ProgressBar.

Inclua o seguinte código JS no header da página que terá o formulário.


<script type="text/javascript">
var progress_key;

$(document).ready(function() {
progress_key = $("#UPLOAD_IDENTIFIER").val();
$("#frmUpload").bind("submit", function() {
beginUpload();
});
$("#uploadprogressbar").progressBar();
});

function beginUpload() {
$("#uploadprogressbar").fadeIn();
setTimeout("showUpload()", 100);
}

function showUpload() {
$.get("<?= $this->url(array('action'=>'process.info')); ?>/id/" + progress_key, function(data) {
if (!data)
return;

var response;
eval ("response = " + data);

if (!response)
return;

var percentage = Math.floor(100 * parseInt(response['bytes_uploaded']) / parseInt(response['bytes_total']));
$("#uploadprogressbar").progressBar(percentage);

});
setTimeout("showUpload()", 100);
}
</script>

Feito isso, é só testar e ver o resultado. :)

Para mais informações do plugin ProgressBar acesse o site do mesmo.

Qualquer dúvida entre em contato que farei o possível para ajudar.

Abraços!

, , , , , ,

  1. #1 by Maurício Vinicius at July 23rd, 2009

    Opa amigo,
    legal um Upload desse! ainda mais com o Zend.
    você poderia me enviar os arquivos? pois o blog está limitando as tags do php e javascript, por isso não consigo visualizar o conteudo completo.
    Abraços.

  2. #2 by Tales at July 24th, 2009

    Olá Maurício,

    já arrumei o conteúdo do artigo para que seja possível visualizar melhor as tags.

    Abraços.

(will not be published)
  1. No trackbacks yet.