Completed
Push — feature/6.x ( db50a0...aa9894 )
by Schlaefer
03:28
created

UploadsController::add()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 54
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 7
eloc 39
c 1
b 0
f 1
nc 6
nop 0
dl 0
loc 54
rs 8.3626

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * Saito - The Threaded Web Forum
6
 *
7
 * @copyright Copyright (c) the Saito Project Developers
8
 * @link https://github.com/Schlaefer/Saito
9
 * @license http://opensource.org/licenses/MIT
10
 */
11
12
namespace ImageUploader\Controller;
13
14
use Api\Controller\ApiAppController;
15
use Api\Error\Exception\GenericApiException;
16
use Cake\Cache\Cache;
17
use Cake\Utility\Security;
18
use ImageUploader\Lib\MimeType;
19
use Psr\Http\Message\UploadedFileInterface;
20
use Saito\Exception\SaitoForbiddenException;
21
use Saito\User\Permission\ResourceAI;
22
23
/**
24
 * Upload Controller
25
 *
26
 * @property \Saito\User\CurrentUser\CurrentUserInterface $CurrentUser
27
 * @property \ImageUploader\Model\Table\UploadsTable $Uploads
28
 */
29
class UploadsController extends ApiAppController
30
{
31
    /**
32
     * {@inheritDoc}
33
     */
34
    public function initialize(): void
35
    {
36
        parent::initialize();
37
        $this->loadModel('Users');
38
        $this->viewBuilder()->setHelpers(['ImageUploader.ImageUploader']);
39
    }
40
41
    /**
42
     * View uploads
43
     *
44
     * @return void
45
     */
46
    public function index()
47
    {
48
        $userId = (int)$this->getRequest()->getQuery('id');
49
        /** @var \App\Model\Entity\User $user */
50
        $user = $this->Users->get($userId);
51
        $permission = $this->CurrentUser->permission(
52
            'saito.plugin.uploader.view',
53
            (new ResourceAI())->onRole($user->getRole())->onOwner($user->getId())
54
        );
55
        if (!$permission) {
56
            throw new SaitoForbiddenException(
57
                sprintf('Attempt to index uploads of "%s".', $userId),
58
                ['CurrentUser' => $this->CurrentUser]
59
            );
60
        }
61
62
        $images = $this->Uploads->find()
63
            ->where(['user_id' => $userId])
64
            ->order(['id' => 'DESC'])
65
            ->all();
66
        $this->set('images', $images);
67
    }
68
69
    /**
70
     * Adds a new upload
71
     *
72
     * @return void
73
     */
74
    public function add()
75
    {
76
        $submitted = $this->request->getData('upload.0.file');
77
        if (
78
            !($submitted instanceof UploadedFileInterface)
79
            || $submitted->getError() !== UPLOAD_ERR_OK
80
        ) {
81
            throw new GenericApiException(__d('image_uploader', 'add.failure'));
82
        }
83
84
        $userId = (int)$this->getRequest()->getData('userId');
85
        /** @var \App\Model\Entity\User $user */
86
        $user = $this->Users->get($userId);
87
        $permission = $this->CurrentUser->permission(
88
            'saito.plugin.uploader.add',
89
            (new ResourceAI())->onRole($user->getRole())->onOwner($user->getId())
90
        );
91
        if (!$permission) {
92
            throw new SaitoForbiddenException(
93
                sprintf('Attempt to add uploads for "%s".', $userId),
94
                ['CurrentUser' => $this->CurrentUser]
95
            );
96
        }
97
98
        $filename = $submitted->getClientFilename();
99
        $parts = explode('.', $filename);
100
        if (count($parts) < 2) {
101
            throw new GenericApiException(__d('image_uploader', 'add.failure.noext'));
102
        }
103
        $ext = array_pop($parts);
104
        $name = $this->CurrentUser->getId() .
105
                '_' .
106
                substr(Security::hash($filename, 'sha256'), 32) .
107
                '.' .
108
                $ext;
109
        $filepath = $submitted->getStream()->getMetadata('uri');
110
        $data = [
111
            'tmp_name' => $filepath,
112
            'name' => $name,
113
            'title' => $filename,
114
            'type' => MimeType::get($filepath, $name),
115
            'size' => filesize($filepath),
116
            'user_id' => $userId,
117
        ];
118
        $document = $this->Uploads->newEntity($data);
119
120
        $entity = $this->Uploads->save($document);
121
        if (!$entity) {
122
            $errors = $document->getErrors();
123
            $msg = $errors ? current(current($errors)) : null;
124
            throw new GenericApiException($msg);
125
        }
126
127
        $this->set('image', $document);
128
    }
129
130
    /**
131
     * Deletes an upload
132
     *
133
     * @param int $imageId the ID of the image to delete
134
     * @return void
135
     */
136
    public function delete($imageId)
137
    {
138
        /** @var \ImageUploader\Model\Entity\Upload $upload */
139
        $upload = $this->Uploads->get($imageId, ['contain' => ['Users']]);
140
        $permission = $this->CurrentUser->permission(
141
            'saito.plugin.uploader.delete',
142
            (new ResourceAI())->onRole($upload->user->getRole())->onOwner($upload->user->getId())
143
        );
144
        if (!$permission) {
145
            throw new SaitoForbiddenException(
146
                sprintf('Attempt to delete upload "%s".', $imageId),
147
                ['CurrentUser' => $this->CurrentUser]
148
            );
149
        }
150
151
        if (!$this->Uploads->delete($upload)) {
152
            $msg = __d('image_uploader', 'delete.failure');
153
            throw new GenericApiException($msg);
154
        }
155
156
        Cache::delete((string)$imageId, 'uploadsThumbnails');
157
158
        $this->autoRender = false;
159
        $this->response = $this->response->withStatus(204);
160
    }
161
}
162