BookmarksController::beforeFilter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 2
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace Bookmarks\Controller;
14
15
use Api\Controller\ApiAppController;
16
use Api\Error\Exception\GenericApiException;
17
use Bookmarks\Model\Table\BookmarksTable;
18
use Cake\Datasource\EntityInterface;
19
use Cake\Event\Event;
20
use Cake\Http\Exception\BadRequestException;
21
use Cake\Http\Exception\MethodNotAllowedException;
22
use Cake\Http\Exception\NotFoundException;
23
use Saito\Exception\SaitoForbiddenException;
24
use Saito\User\Permission\ResourceAI;
25
26
/**
27
 * Bookmarks Controller
28
 *
29
 * @property BookmarksTable $Bookmarks
30
 */
31
class BookmarksController extends ApiAppController
32
{
33
    /**
34
     * Gets all bookmarks for a logged in user
35
     *
36
     * @return void
37
     */
38
    public function index()
39
    {
40
        $categories = $this->CurrentUser->getCategories()->getAll('read');
41
        $bookmarks = $this->Bookmarks->find(
42
            'all',
43
            [
44
                'contain' => ['Entries' => ['Categories', 'Users']],
45
                'conditions' => [
46
                    'Bookmarks.user_id' => $this->CurrentUser->getId(),
47
                    'Entries.category_id IN' => $categories,
48
                ],
49
                'order' => 'Bookmarks.id DESC',
50
            ]
51
        );
52
        $this->set('bookmarks', $bookmarks);
53
    }
54
55
    /**
56
     * Add a new bookmark.
57
     *
58
     * @return void
59
     * @throws MethodNotAllowedException
60
     * @throws BadRequestException
61
     */
62
    public function add()
63
    {
64
        $data = [
65
            'user_id' => $this->CurrentUser->getId(),
66
            'entry_id' => $this->request->getData('entry_id'),
67
        ];
68
69
        $bookmark = $this->Bookmarks->createBookmark($data);
70
        if (!$bookmark) {
71
            throw new GenericApiException('The bookmark could not be created.');
72
        }
73
74
        $this->set('bookmark', $bookmark);
75
    }
76
77
    /**
78
     * Edit a bookmark.
79
     *
80
     * @param int $id bookmark-ID
81
     * @throws MethodNotAllowedException
82
     * @return void
83
     */
84
    public function edit($id)
85
    {
86
        $id = (int)$id;
87
        $bookmark = $this->getBookmark($id);
88
89
        $this->Bookmarks->patchEntity(
90
            $bookmark,
91
            $this->request->getData(),
0 ignored issues
show
Bug introduced by
It seems like $this->request->getData() can also be of type null; however, parameter $data of Cake\ORM\Table::patchEntity() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
            /** @scrutinizer ignore-type */ $this->request->getData(),
Loading history...
92
            ['fields' => ['comment']]
93
        );
94
95
        if (!$this->Bookmarks->save($bookmark)) {
96
            throw new GenericApiException('The bookmark could not be saved.');
97
        }
98
99
        $this->autoRender = false;
100
        $this->response = $this->response->withStatus(204);
101
    }
102
103
    /**
104
     * Delete a single bookmark.
105
     *
106
     * @param int $id bookmark-ID
107
     * @return void
108
     */
109
    public function delete($id)
110
    {
111
        $id = (int)$id;
112
        $bookmark = $this->getBookmark($id);
113
        if (!$this->Bookmarks->delete($bookmark)) {
114
            throw new GenericApiException('The bookmark could not be deleted.');
115
        }
116
117
        $this->autoRender = false;
118
        $this->response = $this->response->withStatus(204);
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     *
124
     * @param Event $event An Event instance
125
     * @return void
126
     */
127
    public function beforeFilter(Event $event)
128
    {
129
        parent::beforeFilter($event);
130
        $this->Security->setConfig('unlockedActions', ['add']);
131
    }
132
133
    /**
134
     * Get a single bookmark
135
     *
136
     * @param int $bookmarkId bookmark-ID
137
     * @throws NotFoundException
138
     * @throws SaitoForbiddenException
139
     * @return EntityInterface
140
     */
141
    private function getBookmark(int $bookmarkId): EntityInterface
142
    {
143
        $bookmark = $this->Bookmarks->find()
144
            ->where(['id' => $bookmarkId])
145
            ->first();
146
147
        if (!$bookmark) {
148
            throw new NotFoundException(__('Invalid bookmark.'));
149
        }
150
151
        $allowed = $this->CurrentUser->permission(
152
            'saito.plugin.bookmarks.delete',
153
            (new ResourceAI())->onOwner($bookmark->get('user_id'))
154
        );
155
        if (!$allowed) {
156
            throw new SaitoForbiddenException(
157
                "Attempt to access bookmark $bookmarkId.",
158
                ['CurrentUser' => $this->CurrentUser]
159
            );
160
        }
161
162
        return $bookmark;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $bookmark could return the type array which is incompatible with the type-hinted return Cake\Datasource\EntityInterface. Consider adding an additional type-check to rule them out.
Loading history...
163
    }
164
}
165