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 App\Controller; |
||||||
14 | |||||||
15 | use App\Controller\Component\AutoReloadComponent; |
||||||
16 | use App\Controller\Component\MarkAsReadComponent; |
||||||
17 | use App\Controller\Component\PostingComponent; |
||||||
18 | use App\Controller\Component\RefererComponent; |
||||||
19 | use App\Controller\Component\ThreadsComponent; |
||||||
20 | use App\Model\Table\EntriesTable; |
||||||
21 | use Cake\Core\Configure; |
||||||
22 | use Cake\Datasource\Exception\RecordNotFoundException; |
||||||
23 | use Cake\Event\Event; |
||||||
24 | use Cake\Http\Exception\BadRequestException; |
||||||
25 | use Cake\Http\Exception\MethodNotAllowedException; |
||||||
26 | use Cake\Http\Exception\NotFoundException; |
||||||
27 | use Cake\Http\Response; |
||||||
28 | use Cake\Routing\RequestActionTrait; |
||||||
29 | use Saito\Exception\SaitoForbiddenException; |
||||||
30 | use Saito\Posting\Basic\BasicPostingInterface; |
||||||
31 | use Saito\User\CurrentUser\CurrentUserInterface; |
||||||
32 | use Saito\User\Permission\ResourceAI; |
||||||
33 | use Stopwatch\Lib\Stopwatch; |
||||||
34 | |||||||
35 | /** |
||||||
36 | * Class EntriesController |
||||||
37 | * |
||||||
38 | * @property CurrentUserInterface $CurrentUser |
||||||
39 | * @property EntriesTable $Entries |
||||||
40 | * @property MarkAsReadComponent $MarkAsRead |
||||||
41 | * @property PostingComponent $Posting |
||||||
42 | * @property RefererComponent $Referer |
||||||
43 | * @property ThreadsComponent $Threads |
||||||
44 | */ |
||||||
45 | class EntriesController extends AppController |
||||||
46 | { |
||||||
47 | use RequestActionTrait; |
||||||
0 ignored issues
–
show
|
|||||||
48 | |||||||
49 | public $helpers = ['Posting', 'Text']; |
||||||
50 | |||||||
51 | /** |
||||||
52 | * {@inheritDoc} |
||||||
53 | */ |
||||||
54 | public function initialize() |
||||||
55 | { |
||||||
56 | parent::initialize(); |
||||||
57 | |||||||
58 | $this->loadComponent('Posting'); |
||||||
59 | $this->loadComponent('MarkAsRead'); |
||||||
60 | $this->loadComponent('Referer'); |
||||||
61 | $this->loadComponent('Threads', ['table' => $this->Entries]); |
||||||
62 | } |
||||||
63 | |||||||
64 | /** |
||||||
65 | * posting index |
||||||
66 | * |
||||||
67 | * @return void|\Cake\Http\Response |
||||||
68 | */ |
||||||
69 | public function index() |
||||||
70 | { |
||||||
71 | Stopwatch::start('Entries->index()'); |
||||||
72 | |||||||
73 | //= determine user sort order |
||||||
74 | $sortKey = 'last_answer'; |
||||||
75 | if (!$this->CurrentUser->get('user_sort_last_answer')) { |
||||||
76 | $sortKey = 'time'; |
||||||
77 | } |
||||||
78 | $order = ['fixed' => 'DESC', $sortKey => 'DESC']; |
||||||
79 | |||||||
80 | //= get threads |
||||||
81 | $threads = $this->Threads->paginate($order, $this->CurrentUser); |
||||||
82 | $this->set('entries', $threads); |
||||||
83 | |||||||
84 | $currentPage = (int)$this->request->getQuery('page') ?: 1; |
||||||
85 | if ($currentPage > 1) { |
||||||
86 | $this->set('titleForLayout', __('page') . ' ' . $currentPage); |
||||||
87 | } |
||||||
88 | if ($currentPage === 1) { |
||||||
89 | if ($this->MarkAsRead->refresh()) { |
||||||
90 | return $this->redirect(['action' => 'index']); |
||||||
91 | } |
||||||
92 | $this->MarkAsRead->next(); |
||||||
93 | } |
||||||
94 | |||||||
95 | // @bogus |
||||||
96 | $this->request->getSession()->write('paginator.lastPage', $currentPage); |
||||||
97 | $this->set('showDisclaimer', true); |
||||||
98 | $this->set('showBottomNavigation', true); |
||||||
99 | $this->Slidetabs->show(); |
||||||
100 | |||||||
101 | $this->_setupCategoryChooser($this->CurrentUser); |
||||||
102 | |||||||
103 | /** @var AutoReloadComponent */ |
||||||
104 | $autoReload = $this->loadComponent('AutoReload'); |
||||||
105 | $autoReload->after($this->CurrentUser); |
||||||
0 ignored issues
–
show
The method
after() does not exist on Cake\Controller\Component . It seems like you code against a sub-type of Cake\Controller\Component such as Cake\Controller\Component\FlashComponent or App\Controller\Component\AutoReloadComponent or Cake\Controller\Component\PaginatorComponent .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
106 | |||||||
107 | Stopwatch::stop('Entries->index()'); |
||||||
108 | } |
||||||
109 | |||||||
110 | /** |
||||||
111 | * Mix view |
||||||
112 | * |
||||||
113 | * @param string $tid thread-ID |
||||||
114 | * @return void|Response |
||||||
115 | * @throws NotFoundException |
||||||
116 | */ |
||||||
117 | public function mix($tid) |
||||||
118 | { |
||||||
119 | $tid = (int)$tid; |
||||||
120 | if ($tid <= 0) { |
||||||
121 | throw new BadRequestException(); |
||||||
122 | } |
||||||
123 | |||||||
124 | try { |
||||||
125 | $postings = $this->Entries->postingsForThread($tid, true, $this->CurrentUser); |
||||||
126 | } catch (RecordNotFoundException $e) { |
||||||
127 | /// redirect sub-posting to mix view of thread |
||||||
128 | $actualTid = $this->Entries->getThreadId($tid); |
||||||
129 | |||||||
130 | return $this->redirect([$actualTid, '#' => $tid], 301); |
||||||
131 | } |
||||||
132 | |||||||
133 | // check if anonymous tries to access internal categories |
||||||
134 | $root = $postings; |
||||||
135 | if (!$this->CurrentUser->getCategories()->permission('read', $root->get('category'))) { |
||||||
136 | return $this->_requireAuth(); |
||||||
137 | } |
||||||
138 | |||||||
139 | $this->_setRootEntry($root); |
||||||
140 | $this->Title->setFromPosting($root, __('view.type.mix')); |
||||||
141 | |||||||
142 | $this->set('showBottomNavigation', true); |
||||||
143 | $this->set('entries', $postings); |
||||||
144 | |||||||
145 | $this->_showAnsweringPanel(); |
||||||
146 | |||||||
147 | $this->Threads->incrementViewsForThread($root, $this->CurrentUser); |
||||||
148 | $this->MarkAsRead->thread($postings); |
||||||
149 | } |
||||||
150 | |||||||
151 | /** |
||||||
152 | * load front page force all entries mark-as-read |
||||||
153 | * |
||||||
154 | * @return void |
||||||
155 | */ |
||||||
156 | public function update() |
||||||
157 | { |
||||||
158 | $this->autoRender = false; |
||||||
159 | $this->CurrentUser->getLastRefresh()->set(); |
||||||
160 | $this->redirect('/entries/index'); |
||||||
161 | } |
||||||
162 | |||||||
163 | /** |
||||||
164 | * Outputs raw markup of an posting $id |
||||||
165 | * |
||||||
166 | * @param string $id posting-ID |
||||||
167 | * @return void |
||||||
168 | */ |
||||||
169 | public function source($id = null) |
||||||
170 | { |
||||||
171 | $this->viewBuilder()->enableAutoLayout(false); |
||||||
172 | $this->view($id); |
||||||
0 ignored issues
–
show
It seems like
$id can also be of type null ; however, parameter $id of App\Controller\EntriesController::view() does only seem to accept string , 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
![]() |
|||||||
173 | } |
||||||
174 | |||||||
175 | /** |
||||||
176 | * View posting. |
||||||
177 | * |
||||||
178 | * @param string $id posting-ID |
||||||
179 | * @return \Cake\Http\Response|void |
||||||
180 | */ |
||||||
181 | public function view(string $id) |
||||||
182 | { |
||||||
183 | $id = (int)$id; |
||||||
184 | Stopwatch::start('Entries->view()'); |
||||||
185 | |||||||
186 | $entry = $this->Entries->get($id); |
||||||
187 | $posting = $entry->toPosting()->withCurrentUser($this->CurrentUser); |
||||||
0 ignored issues
–
show
The method
toPosting() does not exist on Cake\Datasource\EntityInterface . It seems like you code against a sub-type of Cake\Datasource\EntityInterface such as App\Model\Entity\Entry .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
188 | |||||||
189 | if (!$this->CurrentUser->getCategories()->permission('read', $posting->get('category'))) { |
||||||
190 | return $this->_requireAuth(); |
||||||
191 | } |
||||||
192 | |||||||
193 | $this->set('entry', $posting); |
||||||
194 | $this->Threads->incrementViewsForPosting($posting, $this->CurrentUser); |
||||||
195 | $this->_setRootEntry($posting); |
||||||
196 | $this->_showAnsweringPanel(); |
||||||
197 | |||||||
198 | $this->MarkAsRead->posting($posting); |
||||||
199 | |||||||
200 | // inline open |
||||||
201 | if ($this->request->is('ajax')) { |
||||||
202 | return $this->render('/Element/entry/view_posting'); |
||||||
203 | } |
||||||
204 | |||||||
205 | // full page request |
||||||
206 | $this->set( |
||||||
207 | 'tree', |
||||||
208 | $this->Entries->postingsForThread($posting->get('tid'), false, $this->CurrentUser) |
||||||
209 | ); |
||||||
210 | $this->Title->setFromPosting($posting); |
||||||
211 | |||||||
212 | Stopwatch::stop('Entries->view()'); |
||||||
213 | } |
||||||
214 | |||||||
215 | /** |
||||||
216 | * Add new posting. |
||||||
217 | * |
||||||
218 | * @return void|\Cake\Http\Response |
||||||
219 | */ |
||||||
220 | public function add() |
||||||
221 | { |
||||||
222 | $titleForPage = __('Write a New Posting'); |
||||||
223 | $this->set(compact('titleForPage')); |
||||||
224 | } |
||||||
225 | |||||||
226 | /** |
||||||
227 | * Edit posting |
||||||
228 | * |
||||||
229 | * @param string $id posting-ID |
||||||
230 | * @return void|\Cake\Http\Response |
||||||
231 | * @throws NotFoundException |
||||||
232 | * @throws BadRequestException |
||||||
233 | */ |
||||||
234 | public function edit(string $id) |
||||||
235 | { |
||||||
236 | $id = (int)$id; |
||||||
237 | $entry = $this->Entries->get($id); |
||||||
238 | $posting = $entry->toPosting()->withCurrentUser($this->CurrentUser); |
||||||
239 | |||||||
240 | if (!$posting->isEditingAllowed()) { |
||||||
241 | throw new SaitoForbiddenException( |
||||||
242 | 'Access to posting in EntriesController:edit() forbidden.', |
||||||
243 | ['CurrentUser' => $this->CurrentUser] |
||||||
244 | ); |
||||||
245 | } |
||||||
246 | |||||||
247 | // show editing form |
||||||
248 | if (!$posting->isEditingAsUserAllowed()) { |
||||||
249 | $this->Flash->set( |
||||||
250 | __('notice_you_are_editing_as_mod'), |
||||||
251 | ['element' => 'warning'] |
||||||
252 | ); |
||||||
253 | } |
||||||
254 | |||||||
255 | $this->set(compact('posting')); |
||||||
256 | |||||||
257 | // set headers |
||||||
258 | $this->set( |
||||||
259 | 'headerSubnavLeftTitle', |
||||||
260 | __('back_to_posting_from_linkname', $posting->get('name')) |
||||||
261 | ); |
||||||
262 | $this->set('headerSubnavLeftUrl', ['action' => 'view', $id]); |
||||||
263 | $this->set('form_title', __('edit_linkname')); |
||||||
264 | $this->render('/Entries/add'); |
||||||
265 | } |
||||||
266 | |||||||
267 | /** |
||||||
268 | * Get thread-line to insert after an inline-answer |
||||||
269 | * |
||||||
270 | * @param string $id posting-ID |
||||||
271 | * @return void|\Cake\Http\Response |
||||||
272 | */ |
||||||
273 | public function threadLine($id = null) |
||||||
274 | { |
||||||
275 | $posting = $this->Entries->get($id)->toPosting()->withCurrentUser($this->CurrentUser); |
||||||
0 ignored issues
–
show
It seems like
$id can also be of type string ; however, parameter $primaryKey of App\Model\Table\EntriesTable::get() does only seem to accept integer , 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
![]() |
|||||||
276 | if (!$this->CurrentUser->getCategories()->permission('read', $posting->get('category'))) { |
||||||
277 | return $this->_requireAuth(); |
||||||
278 | } |
||||||
279 | |||||||
280 | $this->set('entrySub', $posting); |
||||||
281 | // ajax requests so far are always answers |
||||||
282 | $this->response = $this->response->withType('json'); |
||||||
283 | $this->set('level', '1'); |
||||||
284 | } |
||||||
285 | |||||||
286 | /** |
||||||
287 | * Delete posting |
||||||
288 | * |
||||||
289 | * @param string $id posting-ID |
||||||
290 | * @return void |
||||||
291 | * @throws NotFoundException |
||||||
292 | * @throws MethodNotAllowedException |
||||||
293 | */ |
||||||
294 | public function delete(string $id) |
||||||
295 | { |
||||||
296 | //$this->request->allowMethod(['post', 'delete']); |
||||||
297 | $id = (int)$id; |
||||||
298 | if (!$id) { |
||||||
299 | throw new NotFoundException(); |
||||||
300 | } |
||||||
301 | /* @var Entry $posting */ |
||||||
302 | $posting = $this->Entries->get($id); |
||||||
303 | |||||||
304 | $action = $posting->isRoot() ? 'thread' : 'answer'; |
||||||
305 | $allowed = $this->CurrentUser->getCategories() |
||||||
306 | ->permission($action, $posting->get('category_id')); |
||||||
307 | if (!$allowed) { |
||||||
308 | throw new SaitoForbiddenException(); |
||||||
309 | } |
||||||
310 | |||||||
311 | $success = $this->Entries->deletePosting($id); |
||||||
312 | |||||||
313 | if ($success) { |
||||||
314 | $flashType = 'success'; |
||||||
315 | if ($posting->isRoot()) { |
||||||
316 | $message = __('delete_tree_success'); |
||||||
317 | $redirect = '/'; |
||||||
318 | } else { |
||||||
319 | $message = __('delete_subtree_success'); |
||||||
320 | $redirect = '/entries/view/' . $posting->get('pid'); |
||||||
321 | } |
||||||
322 | } else { |
||||||
323 | $flashType = 'error'; |
||||||
324 | $message = __('delete_tree_error'); |
||||||
325 | $redirect = $this->referer(); |
||||||
326 | } |
||||||
327 | $this->Flash->set($message, ['element' => $flashType]); |
||||||
328 | $this->redirect($redirect); |
||||||
329 | } |
||||||
330 | |||||||
331 | /** |
||||||
332 | * Empty function for benchmarking |
||||||
333 | * |
||||||
334 | * @return void |
||||||
335 | */ |
||||||
336 | public function e() |
||||||
337 | { |
||||||
338 | Stopwatch::start('Entries->e()'); |
||||||
339 | Stopwatch::stop('Entries->e()'); |
||||||
340 | } |
||||||
341 | |||||||
342 | /** |
||||||
343 | * Marks sub-entry $id as solution to its current root-entry |
||||||
344 | * |
||||||
345 | * @param string $id posting-ID |
||||||
346 | * @return void |
||||||
347 | * @throws BadRequestException |
||||||
348 | */ |
||||||
349 | public function solve($id) |
||||||
350 | { |
||||||
351 | $this->autoRender = false; |
||||||
352 | try { |
||||||
353 | $posting = $this->Entries->get($id); |
||||||
0 ignored issues
–
show
$id of type string is incompatible with the type integer expected by parameter $primaryKey of App\Model\Table\EntriesTable::get() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
354 | |||||||
355 | if (empty($posting)) { |
||||||
356 | throw new \InvalidArgumentException('Posting to mark solved not found.'); |
||||||
357 | } |
||||||
358 | |||||||
359 | $rootId = $posting->get('tid'); |
||||||
360 | $rootPosting = $this->Entries->get($rootId); |
||||||
361 | |||||||
362 | $allowed = $this->CurrentUser->permission( |
||||||
363 | 'saito.core.posting.solves.set', |
||||||
364 | (new ResourceAI())->onRole($rootPosting->get('user')->getRole())->onOwner($rootPosting->get('user_id')) |
||||||
365 | ); |
||||||
366 | if (!$allowed) { |
||||||
367 | throw new SaitoForbiddenException( |
||||||
368 | sprintf('Attempt to mark posting %s as solution.', $posting->get('id')), |
||||||
369 | ['CurrentUser' => $this->CurrentUser] |
||||||
370 | ); |
||||||
371 | } |
||||||
372 | |||||||
373 | $value = $posting->get('solves') ? 0 : $rootPosting->get('tid'); |
||||||
374 | $success = $this->Entries->updateEntry($posting, ['solves' => $value]); |
||||||
0 ignored issues
–
show
It seems like
$posting can also be of type array ; however, parameter $posting of App\Model\Table\EntriesTable::updateEntry() does only seem to accept App\Model\Entity\Entry , 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
![]() |
|||||||
375 | |||||||
376 | if (!$success) { |
||||||
0 ignored issues
–
show
|
|||||||
377 | throw new BadRequestException(); |
||||||
378 | } |
||||||
379 | } catch (\Exception $e) { |
||||||
380 | throw new BadRequestException(); |
||||||
381 | } |
||||||
382 | } |
||||||
383 | |||||||
384 | /** |
||||||
385 | * Merge threads. |
||||||
386 | * |
||||||
387 | * @param string $sourceId posting-ID of thread to be merged |
||||||
388 | * @return void |
||||||
389 | * @throws NotFoundException |
||||||
390 | * @td put into admin entries controller |
||||||
391 | */ |
||||||
392 | public function merge(string $sourceId = null) |
||||||
393 | { |
||||||
394 | $sourceId = (int)$sourceId; |
||||||
395 | if (empty($sourceId)) { |
||||||
396 | throw new NotFoundException(); |
||||||
397 | } |
||||||
398 | |||||||
399 | /* @var Entry */ |
||||||
400 | $entry = $this->Entries->findById($sourceId)->first(); |
||||||
0 ignored issues
–
show
The method
findById() does not exist on App\Model\Table\EntriesTable . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
401 | |||||||
402 | if (!$entry || !$entry->isRoot()) { |
||||||
0 ignored issues
–
show
The method
isRoot() does not exist on Cake\Datasource\EntityInterface . It seems like you code against a sub-type of Cake\Datasource\EntityInterface such as App\Model\Entity\Entry .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
403 | throw new NotFoundException(); |
||||||
404 | } |
||||||
405 | |||||||
406 | // perform move operation |
||||||
407 | $targetId = $this->request->getData('targetId'); |
||||||
408 | if (!empty($targetId)) { |
||||||
409 | if ($this->Entries->threadMerge($sourceId, $targetId)) { |
||||||
0 ignored issues
–
show
$targetId of type array|string is incompatible with the type integer expected by parameter $targetId of App\Model\Table\EntriesTable::threadMerge() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
410 | $this->redirect('/entries/view/' . $sourceId); |
||||||
411 | |||||||
412 | return; |
||||||
413 | } else { |
||||||
414 | $this->Flash->set(__('Error'), ['element' => 'error']); |
||||||
415 | } |
||||||
416 | } |
||||||
417 | |||||||
418 | $this->viewBuilder()->setLayout('Admin.admin'); |
||||||
419 | $this->set('posting', $entry); |
||||||
420 | } |
||||||
421 | |||||||
422 | /** |
||||||
423 | * Toggle posting property via ajax request. |
||||||
424 | * |
||||||
425 | * @param string $id posting-ID |
||||||
426 | * @param string $toggle property |
||||||
427 | * |
||||||
428 | * @return \Cake\Http\Response |
||||||
429 | */ |
||||||
430 | public function ajaxToggle($id = null, $toggle = null) |
||||||
431 | { |
||||||
432 | $allowed = ['fixed', 'locked']; |
||||||
433 | if ( |
||||||
434 | !$id |
||||||
435 | || !$toggle |
||||||
436 | || !$this->request->is('ajax') |
||||||
437 | || !in_array($toggle, $allowed) |
||||||
438 | ) { |
||||||
439 | throw new BadRequestException(); |
||||||
440 | } |
||||||
441 | |||||||
442 | $posting = $this->Entries->get($id); |
||||||
0 ignored issues
–
show
$id of type string is incompatible with the type integer expected by parameter $primaryKey of App\Model\Table\EntriesTable::get() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
443 | $data = ['id' => (int)$id, $toggle => !$posting->get($toggle)]; |
||||||
444 | $this->Posting->update($posting, $data, $this->CurrentUser); |
||||||
0 ignored issues
–
show
It seems like
$posting can also be of type array ; however, parameter $entry of App\Controller\Component...tingComponent::update() does only seem to accept App\Model\Entity\Entry , 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
![]() |
|||||||
445 | |||||||
446 | $this->response = $this->response->withType('json'); |
||||||
447 | $this->response = $this->response->withStringBody(json_encode('OK')); |
||||||
448 | |||||||
449 | return $this->response; |
||||||
450 | } |
||||||
451 | |||||||
452 | /** |
||||||
453 | * {@inheritDoc} |
||||||
454 | */ |
||||||
455 | public function beforeFilter(Event $event) |
||||||
456 | { |
||||||
457 | parent::beforeFilter($event); |
||||||
458 | Stopwatch::start('Entries->beforeFilter()'); |
||||||
459 | |||||||
460 | $this->Security->setConfig( |
||||||
461 | 'unlockedActions', |
||||||
462 | ['solve', 'view'] |
||||||
463 | ); |
||||||
464 | $this->Authentication->allowUnauthenticated(['index', 'view', 'mix', 'update']); |
||||||
465 | |||||||
466 | $this->AuthUser->authorizeAction('ajaxToggle', 'saito.core.posting.pinAndLock'); |
||||||
467 | $this->AuthUser->authorizeAction('merge', 'saito.core.posting.merge'); |
||||||
468 | $this->AuthUser->authorizeAction('delete', 'saito.core.posting.delete'); |
||||||
469 | |||||||
470 | Stopwatch::stop('Entries->beforeFilter()'); |
||||||
471 | } |
||||||
472 | |||||||
473 | /** |
||||||
474 | * set view vars for category chooser |
||||||
475 | * |
||||||
476 | * @param CurrentUserInterface $User CurrentUser |
||||||
477 | * @return void |
||||||
478 | */ |
||||||
479 | protected function _setupCategoryChooser(CurrentUserInterface $User) |
||||||
480 | { |
||||||
481 | if (!$User->isLoggedIn()) { |
||||||
482 | return; |
||||||
483 | } |
||||||
484 | $globalActivation = Configure::read( |
||||||
485 | 'Saito.Settings.category_chooser_global' |
||||||
486 | ); |
||||||
487 | if (!$globalActivation) { |
||||||
488 | if ( |
||||||
489 | !Configure::read( |
||||||
490 | 'Saito.Settings.category_chooser_user_override' |
||||||
491 | ) |
||||||
492 | ) { |
||||||
493 | return; |
||||||
494 | } |
||||||
495 | if (!$User->get('user_category_override')) { |
||||||
496 | return; |
||||||
497 | } |
||||||
498 | } |
||||||
499 | |||||||
500 | $this->set( |
||||||
501 | 'categoryChooserChecked', |
||||||
502 | $User->getCategories()->getCustom('read') |
||||||
503 | ); |
||||||
504 | switch ($User->getCategories()->getType()) { |
||||||
505 | case 'single': |
||||||
506 | $title = $User->get('user_category_active'); |
||||||
507 | break; |
||||||
508 | case 'custom': |
||||||
509 | $title = __('Custom'); |
||||||
510 | break; |
||||||
511 | default: |
||||||
512 | $title = __('All Categories'); |
||||||
513 | } |
||||||
514 | $this->set('categoryChooserTitleId', $title); |
||||||
515 | $this->set( |
||||||
516 | 'categoryChooser', |
||||||
517 | $User->getCategories()->getAll('read', 'select') |
||||||
518 | ); |
||||||
519 | } |
||||||
520 | |||||||
521 | /** |
||||||
522 | * Decide if an answering panel is show when rendering a posting |
||||||
523 | * |
||||||
524 | * @return void |
||||||
525 | */ |
||||||
526 | protected function _showAnsweringPanel() |
||||||
527 | { |
||||||
528 | $showAnsweringPanel = false; |
||||||
529 | |||||||
530 | if ($this->CurrentUser->isLoggedIn()) { |
||||||
531 | // Only logged in users see the answering buttons if they … |
||||||
532 | if ( |
||||||
533 | // … directly on entries/view but not inline |
||||||
534 | ($this->request->getParam('action') === 'view' && !$this->request->is('ajax')) |
||||||
535 | // … directly in entries/mix |
||||||
536 | || $this->request->getParam('action') === 'mix' |
||||||
537 | // … inline viewing … on entries/index. |
||||||
538 | || ($this->Referer->wasController('entries') |
||||||
539 | && $this->Referer->wasAction('index')) |
||||||
540 | ) { |
||||||
541 | $showAnsweringPanel = true; |
||||||
542 | } |
||||||
543 | } |
||||||
544 | $this->set('showAnsweringPanel', $showAnsweringPanel); |
||||||
545 | } |
||||||
546 | |||||||
547 | /** |
||||||
548 | * makes root posting of $posting avaiable in view |
||||||
549 | * |
||||||
550 | * @param BasicPostingInterface $posting posting for root entry |
||||||
551 | * @return void |
||||||
552 | */ |
||||||
553 | protected function _setRootEntry(BasicPostingInterface $posting): void |
||||||
554 | { |
||||||
555 | if (!$posting->isRoot()) { |
||||||
556 | /** @var \App\Model\Entity\Entry root */ |
||||||
557 | $root = $this->Entries->find() |
||||||
558 | ->select(['id', 'user_id', 'Users.user_type']) |
||||||
559 | ->where(['Entries.id' => $posting->get('tid')]) |
||||||
560 | ->contain(['Users']) |
||||||
561 | ->first(); |
||||||
562 | $root = $root->toPosting(); |
||||||
563 | } else { |
||||||
564 | $root = $posting; |
||||||
565 | } |
||||||
566 | $this->set('rootEntry', $root); |
||||||
567 | } |
||||||
568 | } |
||||||
569 |
This trait has been deprecated. The supplier of the trait has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.