Download::download()   A
last analyzed

Complexity

Conditions 6
Paths 15

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 19
c 2
b 0
f 0
nc 15
nop 1
dl 0
loc 28
rs 9.0111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Files\Http\Controllers\Api\File;
6
7
use AbterPhp\Files\Service\File\Downloader as DownloadService;
8
use AbterPhp\Framework\Constant\Session;
9
use Casbin\Enforcer;
10
use Casbin\Exceptions\CasbinException;
11
use AbterPhp\Admin\Domain\Entities\User;
12
use AbterPhp\Admin\Orm\UserRepo;
13
use League\Flysystem\FilesystemException;
14
use Opulence\Http\Responses\Response;
15
use Opulence\Http\Responses\ResponseHeaders;
16
use Opulence\Http\Responses\StreamResponse;
17
use Opulence\Routing\Controller;
18
use Opulence\Sessions\ISession;
19
20
class Download extends Controller
21
{
22
    /** @var ISession */
23
    protected $session;
24
25
    /** @var Enforcer */
26
    protected $enforcer;
27
28
    /** @var UserRepo */
29
    protected $userRepo;
30
31
    /** @var DownloadService */
32
    protected $downloadService;
33
34
    /**
35
     * Download constructor.
36
     *
37
     * @param ISession        $session
38
     * @param Enforcer        $enforcer
39
     * @param UserRepo        $userRepo
40
     * @param DownloadService $downloadService
41
     */
42
    public function __construct(
43
        ISession $session,
44
        Enforcer $enforcer,
45
        UserRepo $userRepo,
46
        DownloadService $downloadService
47
    ) {
48
        $this->session         = $session;
49
        $this->enforcer        = $enforcer;
50
        $this->userRepo        = $userRepo;
51
        $this->downloadService = $downloadService;
52
    }
53
54
    /**
55
     * @param string $filesystemName
56
     *
57
     * @return Response
58
     */
59
    public function download(string $filesystemName): Response
60
    {
61
        $user = $this->getUser();
62
        if (null === $user) {
63
            return new Response('', ResponseHeaders::HTTP_NOT_FOUND);
64
        }
65
66
        try {
67
            $entity = $this->downloadService->getUserFile($filesystemName, $user);
68
            if (null === $entity) {
69
                return new Response('', ResponseHeaders::HTTP_NOT_FOUND);
70
            }
71
72
            $streamCallable = $this->downloadService->getStream($entity);
73
74
            $this->downloadService->logDownload($entity, $user);
75
        } catch (CasbinException $e) {
76
            return new Response($e->getMessage(), ResponseHeaders::HTTP_UNAUTHORIZED);
77
        } catch (FilesystemException $e) {
78
            return new Response($e->getMessage(), ResponseHeaders::HTTP_NOT_FOUND);
79
        } catch (\Exception $e) {
80
            return new Response($e->getMessage(), ResponseHeaders::HTTP_INTERNAL_SERVER_ERROR);
81
        }
82
83
        return new StreamResponse(
84
            $streamCallable,
85
            ResponseHeaders::HTTP_OK,
86
            $this->getHeaders($entity->getPublicName())
87
        );
88
    }
89
90
    /**
91
     * @return User|null
92
     */
93
    protected function getUser(): ?User
94
    {
95
        if ($this->session->has(Session::USERNAME)) {
96
            $username = (string)$this->session->get(Session::USERNAME);
97
98
            return $this->userRepo->getByUsername($username);
99
        }
100
101
        return null;
102
    }
103
104
    /**
105
     * @param string $filename
106
     *
107
     * @return array
108
     */
109
    protected function getHeaders(string $filename): array
110
    {
111
        return [
112
            'Content-type'              => 'application/octet-stream',
113
            'Content-Transfer-Encoding' => 'Binary',
114
            'Content-disposition'       => sprintf('attachment; filename=%s', $filename),
115
        ];
116
    }
117
}
118