SPRÁVNÉ ŘEŠENÍ PRO: Přímé stažení souboru v NETTE pomocí redirectu formuláře

Již dříve jsem nastínil jak na to. Ale to bylo řešení postavené na dříve osvojených principech (si všechno napsat sám) a až nyní jsem našel způsob, jak to napsat elegantněji pomocí NETTE.

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();
			$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));
			$this->sendResponse(new DownloadResponse($file, $fileName, array('application/octet-stream', 'application/force-download', 'application/download')));
		} else {
			$this->flashMessage('Nesouhlasí zadané heslo.', 'error');
		}
	}
 
	public function actionDefault() {}
}

Pro pořádek připojuji i obsah šablony:

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

5 komentářů u „SPRÁVNÉ ŘEŠENÍ PRO: Přímé stažení souboru v NETTE pomocí redirectu formuláře

  1. dtr

    Kód je potřeba upravit zhruba takto:
    use Nette\Application\Responses\FileResponse;

    …..

    $httpResponse = $this->context->getService(‚httpResponse‘);
    $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($filepath));
    $this->sendResponse(new FileResponse($filepath, $filename, array(‚application/octet-stream‘, ‚application/force-download‘, ‚application/download‘)));

  2. ales

    Zdravím, díky za návody pro Nette na tomto blogu. Tady je funkční verze pro Nette 2.0.3 na PHP 5.3:

    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->onSuccess[] = callback($this, 'formSubmitted');
            return $form;
        }
     
        public function formSubmitted($form) {
            $file = WWW_DIR . '/data/test.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 = $this->context->getService('httpResponse');
                $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));
                $this->sendResponse(new FileResponse($file, $fileName, array('application/octet-stream', 'application/force-download', 'application/download')));
            } else {
                $this->flashMessage('Nesouhlasí zadané heslo.', 'error');
            }
        }
     
        public function actionDefault() {
     
        }
     
    }//class
  3. Potty

    Díky za návod. Pro funkčnost v Nette 2.0.6 je třeba dát jako parametr FileResponse string místo array.

  4. Petr Lukáš

    Ahoj, díky moc za zveřejnění tohoto, hodně lidem to jistě již pomohlo a pomůž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..