11

Is there a magento utility method available which can help me to create a force content download action ?

  • 1
    which type / extension of files u need to forcefully download? – Fayyaz Khattak Jan 13 '16 at 8:04
18

you can create your controller action by extending \Magento\Backend\App\Action for backend or \Magento\Framework\App\Action\Action for frontend.
and make it look like this:

<?php 
namespace Your\Namespace\Here;

class ClassName extends \Magento\Backend\App\Action 
{
    public function __construct(
        \Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Backend\App\Action\Context $context
    ) {
        $this->resultRawFactory      = $resultRawFactory;
        $this->fileFactory           = $fileFactory;
        parent::__construct($context);
    }
    public function execute()
    {
        //do your custom stuff here
        $fileName = 'file name for download here';
        $this->fileFactory->create(
            $fileName,
            null, //content here. it can be null and set later 
            base dir of the file to download here
            'application/octet-stream', //content type here
            content lenght here...can be null
        );
        $resultRaw = $this->resultRawFactory->create();
        $resultRaw->setContents(contents of file here); //set content for download file here
        return $resultRaw;
    }
}
  • How to pass content in null, i have array of data when passin using above method its define type and function error. – Rakesh Jesadiya May 26 '16 at 7:15
  • 2
    You can directly return the result of $this->fileFactory->create() as this is already a response implementation, no need for $resultRaw – Fabian Schmengler Nov 22 '16 at 10:13
  • @fschmengler you are probably right, but I took this example from the core from the backup download action. – Marius Nov 22 '16 at 10:25
  • 1
    Most M2 core modules are a bad example ;) – Fabian Schmengler Nov 22 '16 at 10:41
  • Yes yes I know the discussion. I actually think I started part of it. But this is not always true – Marius Nov 22 '16 at 10:42
7

Also one can provide a path to a file you would like to be downloaded:

//Send file for download
//@see Magento\Framework\App\Response\Http\FileFactory::create()
return $this->_fileFactory->create(
    //File name you would like to download it by
    $filename,
    [
        'type'  => "filename", //type has to be "filename"
        'value' => "folder/{$filename}", // path will append to the
                                         // base dir
        'rm'    => true, // add this only if you would like the file to be
                         // deleted after being downloaded from server
    ],
    \Magento\Framework\App\Filesystem\DirectoryList::MEDIA
);
2

Based on the answer that Marius gave.

class Download extends \Magento\Framework\App\Action\Action
{
    protected $resultRawFactory;
    protected $fileFactory;

    public function __construct(
        \Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Backend\App\Action\Context $context
    ) {
        $this->resultRawFactory      = $resultRawFactory;
        $this->fileFactory           = $fileFactory;
        parent::__construct($context);
    }
    public function execute()
    {
        try{
            $fileName = 'FileName'; // the name of the downloaded resource
            $this->fileFactory->create(
                $fileName,
                [
                    'type' => 'filename',
                    'value' => 'relative/path/to/file/from/basedir'
                ],
                DirectoryList::MEDIA , //basedir
                'application/octet-stream',
                '' // content length will be dynamically calculated
            );
        }catch (\Exception $exception){
            // Add your own failure logic here
            var_dump($exception->getMessage());
            exit;
        }
        $resultRaw = $this->resultRawFactory->create();
        return $resultRaw;
    }
}

Not having correct permissions (even though a read is needed here the Magento checks for write permissions) will result in a weird error. "The site is down or moved" or smth like that.

It's worth taking a sneak peak at the logic inside $fileFactory->create() as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.