Přímé stažení souboru v NETTE pomocí redirectu formuláře

Potřeboval jsem udělat jednoduché stahovadlo souboru. Požadavky byly, aby pro stažení se muselo zadat heslo a aby soubor nešlo ani následně stahovat přes nějakou konstantní URL.

Níže uváděné řešení již považuji za zastaralé a nechávám ho tady jen aby bylo možné porovnat, že i toto jde v NETTE napsat lépe. Pokračujte zde…


Řešení je nakonec triviální:
Presenter:

< ?php class PcClientPresenter extends BasePresenter {
 	protected function createComponentForm($name) {
 		$form = new AppForm($this, $name);
 		$form->addPassword('heslo', 'Heslo: ')
			->addRule(Form::FILLED, 'Heslo musí být vyplněné.');
		$form->addSubmit('send', 'Stáhnout soubor »');
 
		$form->onSubmit[] = array($this, 'formSubmitted');
	}
 
	public function formSubmitted($form) {
		$file = WWW_DIR . '/data/soubor.zip'; // soubor může být úplně mimo web root (=nestáhnutelný pomocí URL)
		$fileName = 'Soubor po stažení.zip'; // název pod kterým se bude soubor stahovat uživateli
 
		$arr = $form->getValues();
		if ($arr['heslo'] === 'HESLO') {
			$httpResponse = Environment::getHttpResponse();
			// Pošleme prohlížeči hlavičky pomocí kterých mu řekneme že se jedná o stahování
			$httpResponse->setContentType('application/octet-stream');
			$httpResponse->setContentType('application/force-download');
			$httpResponse->setContentType('application/download');
			$httpResponse->setHeader('Pragma', "public");
			$httpResponse->setHeader('Expires', 0);
			$httpResponse->setHeader('Cache-Control', "must-revalidate, post-check=0, pre-check=0");
			$httpResponse->setHeader('Content-Transfer-Encoding', "binary");
			$httpResponse->setHeader('Content-Description', "File Transfer");
			$httpResponse->setHeader('Content-Length', filesize($file));
			$httpResponse->setHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"');
 
			// v cyklu načítáme postupně soubor a posíláme ho prohlížeči (u malých souborů by to šlo najednou ale u velkých by došla dostupná paměť pro PHP)
			$fp = fopen($file, 'r');
			while (!feof($fp)) {
				echo fread($fp, 65536);
				flush();
			}
			fclose($fp);
			$this->terminate();
		} else {
			$this->flashMessage('Nesouhlasí zadané heslo.', 'error');
		}
	}
 
	public function actionDefault() {}
}

Template:

{block #content}
<h1>Stažení PC klienta</h1>
<div class="flash {$flash->type}">{$flash->message}</div>
{control form}
{/block}


Vše!

Napsat komentář

Vaše emailová adresa nebude zveřejněna.

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..