atk4 / filestore

Implements integration between ATK UI and FlySystem
https://agiletoolkit.org/
MIT License
9 stars 8 forks source link

Implement download file #10

Open mkrecek234 opened 4 years ago

mkrecek234 commented 4 years ago

Are there any activities to implement also the download part?

mkrecek234 commented 4 years ago

Here is a very basic simple code (Work in progress) to create a download wrapper:

<?php
namespace atk4\crm;

include '../vendor/autoload.php';
include '../src/db.php';

$dsn = 'mysql://root:root@localhost:8889/db;
$db = \atk4\data\Persistence::connect($dsn);

$fs = new \atk4\filestore\Model\File($db, 'filestore_file');

$token =  $_GET["token"];

$fs->addCondition('token', $token);
$fs->loadAny();
$meta_filename = $fs['meta_filename'];
$filename = $fs['location'];

$adapter = new \League\Flysystem\Adapter\Local(__DIR__.'/../src/localfiles');
$fsa = new \League\Flysystem\Filesystem($adapter);

if ($fsa->has($filename)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.$meta_filename.'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . $fsa->getSize($filename));
    $stream = $fsa->readStream($filename);
    $contents = stream_get_contents($stream);
    echo $contents;
    fclose($stream);
    exit;
} else {
    echo "Fehler - Datei nicht gefunden: ".$filename;
}
mkrecek234 commented 4 years ago

Here is a more ATK4 style way for a download wrapper thanks to the hints of @abbadon1334 - however there are still 2 issues with this: 1) the stickyGet of the token does not "survive" an atk4/login login but the token is lost. 2) I don't like the button to call the callback, I would fancy a direct download. Since we are not supposed to run app->terminate directly but via callback, how can I make the callback immediately...

<?php
namespace atk4\crm;

include '../vendor/autoload.php';
include '../src/db.php';

$app = new \atk4\crm\CRMApp();

$fs = new \atk4\filestore\Model\File($app->db);
$token = $app->stickyGet('token');

$fs->addCondition('token', $token);
$fs->tryloadAny();
$meta_filename = $fs['meta_filename'];
$filename = $fs['location'];

$adapter = new \League\Flysystem\Adapter\Local(__DIR__.'/../src/localfiles');
$fsa = new \League\Flysystem\Filesystem($adapter);

if ($app->auth->user->loaded()) {
  if ($fsa->has($filename)) {

    $callback = \atk4\ui\Callback::addTo($app);
    $callback->set(function() use ($app, $fsa, $filename, $meta_filename) {
        $stream = $fsa->readStream($filename);
        $contents = stream_get_contents($stream);
        fclose($stream);

        $app->terminate($contents,[
            'Content-Description' => 'File Transfer',
            'Content-Type' => 'application/octet-stream',
            'Cache-Control' =>  'must-revalidate',
            'Expires' => '0',
            'Content-Disposition' => 'attachment; filename="'.$meta_filename.'"',
            'Content-Length' => $fsa->getSize($filename),
            'Pragma' => 'public'
        ]);
    });

   \atk4\ui\Button::addTo($app,['Download now'])->link($callback->getURL());

} else {
    $message = new \atk4\ui\Message(['File not found', 'error']); 
    $app->add($message);
}

}
DarkSide666 commented 1 year ago

@mkrecek234 Please check demos in current develop branch. Download functionality is implemented now. Is that enough and this issue ticket can be closed now?