Hey there,
recently I was working with calendar files for events, and serving them by returning a snippet via route works fine.
However, I’d like to implement these ics files as virtual files which is much cleaner on the frontend and allows for stuff like niceSize() (custom file class etc), but how would I get the virtual file content (which is a string, basically) to represent the file? Has anybody done this before? I don’t see how new File() would be of any use there …
Would I implement something like public function content() … ?
I think it’s not that easy. Of course you could assign your string value to content, and then return that somehow, but you wouldn’t be able to do a file_get_contents unless you store the string in a data uri. And yes, you can find a way to estimate the future size of such a file through php://memory. But I wonder if there is really anything to be gained by this.
I moved the calendar stream & export code from read() to __construct() and saved it as $this->calendar, then created these two (rather primitive) methods:
/**
* Returns the raw size of the file
*
* @return int
*/
public function size(): int
{
return strlen($this->calendar);
}
/**
* Returns the file size in a human-readable format
*
* @return string
*/
public function niceSize(): string
{
$size = $this->size();
# the math magic
$size = round($size / pow(1024, ($unit = floor(log($size, 1024)))), 2);
return $size . ' ' . Kirby\Toolkit\F::$units[$unit];
}
… to provide low-level filesize. Thanks again, @rasteiner !
note that this creates the “file” (the export) every time the page is loaded. Even if you don’t access it, or its size. It’s probably not a problem, but if you want to be a bit more conservative, you could keep the code in read and instead cache it there. Like:
public function read()
{
if($this->calendar) return $this->calendar;
//else create $this->calendar and return it
}
public function size(): int
{
return strlen($this->read());
}
// etc...
Mhh, using an a tag (with download attribute, etc) doesn’t provide a working download link for $file->url() - what am I doing wrong? I didn’t change anything except adding the two functions as stated above - how did you manage to let people download your calendar file?