13 de junho de 2011

Servir documentos através de uma action

Por vezes, torna-se necessários servir ficheiros privados, que em vez de estarem no diretório público web/uploads, devem ficar fora de web, impedindo o acesso direto, cabendo a uma action verificar se o utilizador tem permissões e então entregar o ficheiro. Eis como o fazer através do object sfResponse numa action:

public function executeBackup(sfWebRequest $request)
{
// realizar backup da base de dados e dos uploads
$this->setLayout(false);
$this->setTemplate(false);
sfConfig::set('sf_web_debug', false);

// nome do ficheiro tem de coincidir com o definido na task uacBackupTask
$file_cache = sfConfig::get('sf_data_dir').'/backup/backup_'.date('Y-m-d').'.zip';
// verificar se existe ficheiro de backup criado pela task, se sim, entrega esse, senão gera novo
if (file_exists($file_cache))
{
$file = $file_cache;
}
else
{
$file = adcBackup::execute(); // cria o ficheiro e envia o caminho absoluto
$backup = sfConfig::get('sf_data_dir').'/backup/'.basename($file);
@copy($file, $backup);
@chmod($backup, 0666);
}

// check if the file exists
$this->forward404Unless(file_exists($file));

// Adding the file to the Response object
$this->getResponse()->clearHttpHeaders();
$this->getResponse()->addCacheControlHttpHeader('Cache-control','must-revalidate, post-check=0, pre-check=0');
$this->getResponse()->setHttpHeader('Pragma: public', true);
$this->getResponse()->setContentType('application/zip');
$this->getResponse()->setHttpHeader('Content-Disposition','attachment; filename='.basename($file), true);
$this->getResponse()->sendHttpHeaders();
$this->getResponse()->setContent(file_get_contents($file));

return sfView::NONE;
}

Nenhum comentário:

Postar um comentário