1

I'm using CakePHP 3.4+ for my application.

There is an XML file in local path and needs to be downloaded when on clicking the link. I want to return download from controller's action after checking few requirements as per my application

public function downloadXml()
{
    if ($this->_checkMembership()) {
        try {
            // file path /webroot/agency/data.xml
            $xmlLink = WWW_ROOT . 'agency/data.xml';

            $this->response->withFile($xmlLink, [
                'download' => true,
                'name' => 'data.xml',
            ]);
            return $this->response;
        } catch (NotFoundException $e) {
            $this->Flash->error('Requested file not found. Try again');
            return $this->redirect(['action' => 'index']);
        }
    }
}

And in template

<?= $this->Html->link(
      __('Download the site'),
      [
          'action' => 'downloadXml'
      ],
) ?>

But this only shows a blank page on clicking the link

Tazbirul Haque
  • 233
  • 1
  • 3
  • 15
Anuj TBE
  • 9,198
  • 27
  • 136
  • 285

1 Answers1

4

The with* reponse methods are implemented using the PSR-7 immutability pattern, ie they return a new object instead of modifying the current one. You must return the newly created object:

return $this->response->withFile($xmlLink, [
    'download' => true,
    'name' => 'data.xml',
]);

If you weren't to return a custom response, ie if you'd wanted to render a view instead of returning a response object, then you'd have to reassign the new object to $this->response in order to apply modifications.

ndm
  • 59,784
  • 9
  • 71
  • 110