$file->download() loads 0 byte - Empty File

i am trying to use the $file->download() method in v3 and i am having trouble.

my $file is set up properly

    [hash] => bd1addf8d8dfbcc7c1da2cc19b18eb92
    [filename] => float-panel-2.zip
    [name] => float-panel-2
    [safeName] => float-panel-2
    [extension] => zip
    [size] => 203151
    [niceSize] => 198,39 kB
    [modified] => 2018-11-15T12:29:10+00:00
    [mime] => application/zip
    [type] => archive
    [isWritable] => 1
 [url] => http://v3.test/media/pages/product2/1697901891-1542284950/float-panel-2.zip

when the download method is called it’s starting a download with the correct file/filename, but the file downloaded has 0 bytes and is obviously empty.

i am pretty much using the function vanilla inside a function declaration after checking a few things…

// $file object as seen above

are you calling it in a route, controller or template?

the function is declared in a seperate file which will be loaded by plugin/my-plugin/index.php

function fileDownload($var1,$var2){
// ...

the function itself is called in a route

<?php return [
    'pattern' => '(:any)/download/(:any)',
    'action' => function($language,$file){
       // some stuff happening....
      // $page & $file var is set correctly, as mentioned the $file object within the function returns the correct file which should download
        fileDownload($page, $file);
]; ?>

You use two variables here, but you have only one placeholder… that won’t work as expected.

that’s not the problem here, before posting the code i edited out some unnecessary stuff and put in that error here.

my code will run though some pages and structures to get the $file object ready, i was trying to strip down a bit before posting.

as i mentioned. everything seems to get set up correctly, the $file object is returning everything from size and filename, but when the actual $file->download() is happening, it’ll return 0 bytes.

And there is no $file->download() method… at least I can’t find one.

there is one…

i replaced $file->download() with the following, and this seems to work fine.

// from here https://stackoverflow.com/questions/7263923/how-to-force-file-download-with-php
                        header('Content-Type: application/octet-stream');
                        header("Content-Transfer-Encoding: Binary"); 
                        header("Content-disposition: attachment; filename=\"" . basename($file->url()) . "\""); 
                        readfile($file->url()); // do the double-download-dance (dirty but worky)

If you say so, maybe you can show me where it is?

you mean in the kirby core, there is no download() method? well ok, i have checked the docs and was wondering why i couldn’t find it anymore, there has been a download method before, and somehow some things still happen, …


There are three download methods in the Kirby core, but no $file->download() (as in Kirby\Cms\File) method. Maybe it inherits from the image class, though, haven’t checked.

Ah, ok, it triggers a download…

well ok, so maybe i expected the unexpected. in v2 there was a $file->download() method, and before i checked the docs some things were still happening when using the download() method (with a $file object) which led me to believe it’s still there

after checking the docs it seemed like the method is not documented, so i was taking a shot here. If that method is gone (or never was there to begin with) … that’s fine.

I can still use the solution i have…

There is in fact a download method in the Kirby\Image\Image class and $file->download does in fact download something, but when I do that, I only get a file with an html extension …

Hi :slight_smile: Im currently migrating from Kirby 2 to 3.

I used this function too but in Kirby 3 it breaks :frowning:
My use case was to force download a pdf file after a form was submitted.

Blueprint field:

label: Pdf File after Download
type: select
options: documents
width: 1/3

Php to Download file

$file = $page->mypdf();

Please help. Thanks in advance.

if ($file = $page->mypdf()->toFile()) {

// or shorter
($file = $page->mypdf()->toFile()) ? $file->download() : false;

Your code would actually work as well (but is more verbose), but you should never call a class method without making sure to have an object of that class.

Thanks Sonja for the quick response, im still learning the basics and dos and don’ts of Kirby.

Your code works :wink: But!.. It downloads not the expected file - just putting the source of the the current page in a file and download it. Mehh. But the workaround from carsten did it.