Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

BasketController::sendMail()   B
last analyzed

Complexity

Conditions 7
Paths 24

Size

Total Lines 66
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 40
c 0
b 0
f 0
nc 24
nop 0
dl 0
loc 66
rs 8.3466

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
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Controller;
14
15
use Kitodo\Dlf\Common\Helper;
16
use Kitodo\Dlf\Domain\Model\ActionLog;
17
use Kitodo\Dlf\Domain\Model\Basket;
18
use Kitodo\Dlf\Domain\Repository\ActionLogRepository;
19
use Kitodo\Dlf\Domain\Repository\MailRepository;
20
use Kitodo\Dlf\Domain\Repository\BasketRepository;
21
use Kitodo\Dlf\Domain\Repository\PrinterRepository;
22
use Psr\Http\Message\ResponseInterface;
23
use TYPO3\CMS\Core\Mail\MailMessage;
24
use TYPO3\CMS\Core\Utility\GeneralUtility;
25
use TYPO3\CMS\Core\Utility\MailUtility;
26
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
27
use TYPO3\CMS\Core\Context\Context;
28
29
/**
30
 * Controller class for the plugin 'Basket'.
31
 *
32
 * @package TYPO3
33
 * @subpackage dlf
34
 *
35
 * @access public
36
 */
37
class BasketController extends AbstractController
38
{
39
    /**
40
     * @access protected
41
     * @var BasketRepository
42
     */
43
    protected BasketRepository $basketRepository;
44
45
    /**
46
     * @access public
47
     *
48
     * @param BasketRepository $basketRepository
49
     *
50
     * @return void
51
     */
52
    public function injectBasketRepository(BasketRepository $basketRepository): void
53
    {
54
        $this->basketRepository = $basketRepository;
55
    }
56
57
    /**
58
     * @access protected
59
     * @var MailRepository
60
     */
61
    protected MailRepository $mailRepository;
62
63
    /**
64
     * @access public
65
     *
66
     * @param MailRepository $mailRepository
67
     *
68
     * @return void
69
     */
70
    public function injectMailRepository(MailRepository $mailRepository): void
71
    {
72
        $this->mailRepository = $mailRepository;
73
    }
74
75
    /**
76
     * @access protected
77
     * @var PrinterRepository
78
     */
79
    protected PrinterRepository $printerRepository;
80
81
    /**
82
     * @access public
83
     *
84
     * @param PrinterRepository $printerRepository
85
     *
86
     * @return void
87
     */
88
    public function injectPrinterRepository(PrinterRepository $printerRepository): void
89
    {
90
        $this->printerRepository = $printerRepository;
91
    }
92
93
    /**
94
     * @access protected
95
     * @var ActionLogRepository
96
     */
97
    protected ActionLogRepository $actionLogRepository;
98
99
    /**
100
     * @access public
101
     *
102
     * @param ActionLogRepository $actionLogRepository
103
     *
104
     * @return void
105
     */
106
    public function injectActionLogRepository(ActionLogRepository $actionLogRepository): void
107
    {
108
        $this->actionLogRepository = $actionLogRepository;
109
    }
110
111
    /**
112
     * Different actions which depends on the chosen action (form)
113
     * 
114
     * @access public
115
     *
116
     * @return ResponseInterface the response
117
     */
118
    public function basketAction(): ResponseInterface
119
    {
120
        $basket = $this->getBasketData();
121
122
        // action remove from basket
123
        if ($this->requestData['basket_action'] === 'remove') {
124
            // remove entry from list
125
            if (isset($this->requestData['selected'])) {
126
                $basket = $this->removeFromBasket($this->requestData, $basket);
0 ignored issues
show
Unused Code introduced by
The assignment to $basket is dead and can be removed.
Loading history...
127
            }
128
        }
129
        // action remove from basket
130
        if ($this->requestData['basket_action'] == 'download') {
131
            // open selected documents
132
            if (isset($this->requestData['selected'])) {
133
                $pdfUrl = $this->settings['pdfgenerate'];
134
                foreach ($this->requestData['selected'] as $docValue) {
135
                    if ($docValue['id']) {
136
                        $docData = $this->getDocumentData((int) $docValue['id'], $docValue);
137
                        $pdfUrl .= $docData['urlParams'] . $this->settings['pdfparamseparator'];
138
                        $this->redirectToUri($pdfUrl);
139
                    }
140
                }
141
            }
142
        }
143
        // action print from basket
144
        if ($this->requestData['print_action']) {
145
            // open selected documents
146
            if (isset($this->requestData['selected'])) {
147
                $this->printDocument();
148
            }
149
        }
150
        // action send mail
151
        if ($this->requestData['mail_action']) {
152
            if (isset($this->requestData['selected'])) {
153
                $this->sendMail();
154
            }
155
        }
156
157
        return $this->redirect('main');
158
    }
159
160
    /**
161
     * Add documents to the basket
162
     *
163
     * @access public
164
     *
165
     * @return ResponseInterface the response
166
     */
167
    public function addAction(): ResponseInterface
168
    {
169
        $basket = $this->getBasketData();
170
171
        if (
172
            !empty($this->requestData['id'])
173
            && $this->requestData['addToBasket']
174
        ) {
175
            $basket = $this->addToBasket($this->requestData, $basket);
0 ignored issues
show
Unused Code introduced by
The assignment to $basket is dead and can be removed.
Loading history...
176
        }
177
178
        return $this->redirect('main');
179
    }
180
181
    /**
182
     * The main method of the plugin
183
     *
184
     * @access public
185
     *
186
     * @return ResponseInterface the response
187
     */
188
    public function mainAction(): ResponseInterface
189
    {
190
        $basket = $this->getBasketData();
191
192
        $countDocs = 0;
193
        if ($basket->getDocIds()) {
194
            $countDocs = count(json_decode($basket->getDocIds(), true));
195
        }
196
        $this->view->assign('countDocs', $countDocs);
197
198
        $allMails = $this->mailRepository->findAllWithPid($this->settings['storagePid']);
199
200
        $mailSelect = [];
201
        if ($allMails->count() > 0) {
202
            $mailSelect[0] = htmlspecialchars(LocalizationUtility::translate('basket.chooseMail', 'dlf'));
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...ket.chooseMail', 'dlf') can also be of type null; however, parameter $string of htmlspecialchars() 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 ignore-type  annotation

202
            $mailSelect[0] = htmlspecialchars(/** @scrutinizer ignore-type */ LocalizationUtility::translate('basket.chooseMail', 'dlf'));
Loading history...
203
            foreach ($allMails as $mail) {
204
                $mailSelect[$mail->getUid()] = htmlspecialchars($mail->getName()) . ' (' . htmlspecialchars($mail->getMail()) . ')';
205
            }
206
            $this->view->assign('mailSelect', $mailSelect);
207
        }
208
209
        $allPrinter = $this->printerRepository->findAll();
210
211
        $printSelect = [];
212
        if ($allPrinter->count() > 0) {
213
            $printSelect[0] = htmlspecialchars(LocalizationUtility::translate('basket.choosePrinter', 'dlf'));
214
            foreach ($allPrinter as $printer) {
215
                $printSelect[$printer->getUid()] = htmlspecialchars($printer->getLabel());
216
            }
217
            $this->view->assign('printSelect', $printSelect);
218
        }
219
220
        $entries = [];
221
        if ($basket->getDocIds()) {
222
            // get each entry
223
            foreach (json_decode($basket->getDocIds()) as $value) {
224
                $entries[] = $this->getEntry($value);
225
            }
226
            $this->view->assign('entries', $entries);
227
        }
228
229
        return $this->htmlResponse();
230
    }
231
232
    /**
233
     * The basket data from user session.
234
     * 
235
     * @access protected
236
     *
237
     * @return Basket The found data from user session.
238
     */
239
    protected function getBasketData(): Basket
240
    {
241
        // get user session
242
        $userSession = $GLOBALS['TSFE']->fe_user->getSession();
243
244
        // Checking if a user is logged in
245
        $userIsLoggedIn = $this->isUserLoggedIn();
246
247
        if ($userIsLoggedIn) {
248
            $basket = $this->basketRepository->findOneByFeUserId((int) $GLOBALS['TSFE']->fe_user->user['uid']);
0 ignored issues
show
Bug introduced by
The method findOneByFeUserId() does not exist on Kitodo\Dlf\Domain\Repository\BasketRepository. 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 ignore-call  annotation

248
            /** @scrutinizer ignore-call */ 
249
            $basket = $this->basketRepository->findOneByFeUserId((int) $GLOBALS['TSFE']->fe_user->user['uid']);
Loading history...
249
        } else {
250
            $userSession->set('ses', 'tx_dlf_basket', '');
251
            $userSession->dataWasUpdated();
252
            $GLOBALS['TSFE']->fe_user->storeSessionData();
253
254
            $basket = $this->basketRepository->findOneBySessionId($userSession->getIdentifier());
0 ignored issues
show
Bug introduced by
The method findOneBySessionId() does not exist on Kitodo\Dlf\Domain\Repository\BasketRepository. 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 ignore-call  annotation

254
            /** @scrutinizer ignore-call */ 
255
            $basket = $this->basketRepository->findOneBySessionId($userSession->getIdentifier());
Loading history...
255
        }
256
257
        // session does not exist
258
        if ($basket === null) {
259
            // create new basket in db
260
            $basket = GeneralUtility::makeInstance(Basket::class);
261
            $basket->setSessionId($userSession->getIdentifier());
262
            $basket->setFeUserId($userIsLoggedIn ? $GLOBALS['TSFE']->fe_user->user['uid'] : 0);
263
        }
264
265
        return $basket;
266
    }
267
268
    /**
269
     * Return one basket entry
270
     *
271
     * @access protected
272
     *
273
     * @param bool|null|object $data DocumentData
274
     *
275
     * @return array One basket entry
276
     */
277
    protected function getEntry($data): array
278
    {
279
        if (is_object($data)) {
280
            $data = get_object_vars($data);
281
        }
282
        $id = $data['id'];
283
        $startPage = $data['startpage'];
284
        $endPage = $data['endpage'];
285
        $startX = $data['startX'];
286
        $startY = $data['startY'];
287
        $endX = $data['endX'];
288
        $endY = $data['endY'];
289
        $rotation = $data['rotation'];
290
291
        $docData = $this->getDocumentData((int) $id, $data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type boolean and null; however, parameter $data of Kitodo\Dlf\Controller\Ba...ller::getDocumentData() 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

291
        $docData = $this->getDocumentData((int) $id, /** @scrutinizer ignore-type */ $data);
Loading history...
292
293
        $entryKey = $id . '_' . $startPage;
294
        if (!empty($startX)) {
295
            $entryKey .= '_' . $startX;
296
        }
297
        if (!empty($endX)) {
298
            $entryKey .= '_' . $endX;
299
        }
300
301
        $entry = [
302
            'BASKETDATA' => $docData,
303
            'id' => $id,
304
            'NUMBER' => $docData['record_id'],
305
            'key' => $entryKey
306
        ];
307
308
        $entry['CONTROLS'] = [
309
            'startpage' => $startPage,
310
            'endpage' => $endPage,
311
            'startX' => $startX,
312
            'startY' => $startY,
313
            'endX' => $endX,
314
            'endY' => $endY,
315
            'rotation' => $rotation,
316
        ];
317
318
        // return one entry
319
        return $entry;
320
    }
321
322
    /**
323
     * Returns the download url configured in the basket
324
     *
325
     * @access protected
326
     *
327
     * @param int $id Document id
328
     * @param array $data DocumentData
329
     *
330
     * @return array|false download url or false
331
     */
332
    protected function getDocumentData(int $id, array $data)
333
    {
334
        // get document instance to load further information
335
        $this->loadDocument((int) $id);
336
        if (isset($this->document)) {
337
            // replace url param placeholder
338
            // TODO: Parameter #2 $replace of function str_replace expects array|string, int given.
339
            // @phpstan-ignore-next-line
340
            $urlParams = str_replace("##page##", (int) $data['page'], $this->settings['pdfparams']);
341
            $urlParams = str_replace("##docId##", $this->document->getRecordId(), $urlParams);
0 ignored issues
show
Bug introduced by
The method getRecordId() does not exist on null. ( Ignorable by Annotation )

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

341
            $urlParams = str_replace("##docId##", $this->document->/** @scrutinizer ignore-call */ getRecordId(), $urlParams);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
342
            // TODO: Parameter #2 $replace of function str_replace expects array|string, int given.
343
            // @phpstan-ignore-next-line
344
            $urlParams = str_replace("##startpage##", (int) $data['startpage'], $urlParams);
345
            if ($data['startpage'] != $data['endpage']) {
346
                $urlParams = str_replace("##endpage##", $data['endpage'] === "" ? "" : (int) $data['endpage'], $urlParams);
347
            } else {
348
                // remove parameter endpage
349
                $urlParams = str_replace(",##endpage##", '', $urlParams);
350
            }
351
            $urlParams = str_replace("##startx##", $data['startX'] === "" ? "" : (int) $data['startX'], $urlParams);
352
            $urlParams = str_replace("##starty##", $data['startY'] === "" ? "" : (int) $data['startY'], $urlParams);
353
            $urlParams = str_replace("##endx##", $data['endX'] === "" ? "" : (int) $data['endX'], $urlParams);
354
            $urlParams = str_replace("##endy##", $data['endY'] === "" ? "" : (int) $data['endY'], $urlParams);
355
            $urlParams = str_replace("##rotation##", $data['rotation'] === "" ? "" : (int) $data['rotation'], $urlParams);
356
357
            $downloadUrl = $this->settings['pdfgenerate'] . $urlParams;
358
359
            $title = $this->document->getTitle();
360
            if (empty($title)) {
361
                $title = LocalizationUtility::translate('basket.noTitle', 'dlf') ? : '';
362
            }
363
364
            // Set page and cutout information
365
            $info = '';
366
            if ($data['startX'] != '' && $data['endX'] != '') {
367
                // cutout
368
                $info .= htmlspecialchars(LocalizationUtility::translate('basket.cutout', 'dlf')) . ' ';
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...'basket.cutout', 'dlf') can also be of type null; however, parameter $string of htmlspecialchars() 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 ignore-type  annotation

368
                $info .= htmlspecialchars(/** @scrutinizer ignore-type */ LocalizationUtility::translate('basket.cutout', 'dlf')) . ' ';
Loading history...
369
            }
370
            if ($data['startpage'] == $data['endpage']) {
371
                // One page
372
                $info .= htmlspecialchars(LocalizationUtility::translate('page', 'dlf')) . ' ' . $data['startpage'];
373
            } else {
374
                $info .= htmlspecialchars(LocalizationUtility::translate('page', 'dlf')) . ' ' . $data['startpage'] . '-' . $data['endpage'];
375
            }
376
            $downloadLink = '<a href="' . $downloadUrl . '" target="_blank">' . htmlspecialchars($title) . '</a> (' . $info . ')';
377
            if ($data['startpage'] == $data['endpage']) {
378
                $pageNums = 1;
379
            } else {
380
                $pageNums = $data['endpage'] - $data['startpage'];
381
            }
382
            return [
383
                'downloadUrl' => $downloadUrl,
384
                'title' => $title,
385
                'info' => $info,
386
                'downloadLink' => $downloadLink,
387
                'pageNums' => $pageNums,
388
                'urlParams' => $urlParams,
389
                'record_id' => $this->document->getRecordId(),
390
            ];
391
        }
392
        return false;
393
    }
394
395
    /**
396
     * Adds documents to the basket and includes JS
397
     *
398
     * @access protected
399
     *
400
     * @param array $piVars piVars
401
     * @param Basket $basket basket object
402
     *
403
     * @return Basket|null Basket data
404
     */
405
    protected function addToBasket(array $piVars, Basket $basket): ?Basket
406
    {
407
        $output = '';
408
409
        if (!$piVars['startpage']) {
410
            $page = 0;
411
        } else {
412
            $page = (int) $piVars['startpage'];
413
        }
414
        if ($page != null || $piVars['addToBasket'] == 'list') {
415
            $documentItem = [
416
                'id' => (int) $piVars['id'],
417
                'startpage' => (int) $piVars['startpage'],
418
                'endpage' => !isset($piVars['endpage']) || $piVars['endpage'] === "" ? "" : (int) $piVars['endpage'],
419
                'startX' => !isset($piVars['startX']) || $piVars['startX'] === "" ? "" : (int) $piVars['startX'],
420
                'startY' => !isset($piVars['startY']) || $piVars['startY'] === "" ? "" : (int) $piVars['startY'],
421
                'endX' => !isset($piVars['endX']) || $piVars['endX'] === "" ? "" : (int) $piVars['endX'],
422
                'endY' => !isset($piVars['endY']) || $piVars['endY'] === "" ? "" : (int) $piVars['endY'],
423
                'rotation' => !isset($piVars['rotation']) || $piVars['rotation'] === "" ? "" : (int) $piVars['rotation']
424
            ];
425
426
            // update basket
427
            if (!empty(json_decode($basket->getDocIds()))) {
0 ignored issues
show
Bug introduced by
It seems like $basket->getDocIds() can also be of type null; however, parameter $json of json_decode() 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 ignore-type  annotation

427
            if (!empty(json_decode(/** @scrutinizer ignore-type */ $basket->getDocIds()))) {
Loading history...
428
                $items = json_decode($basket->getDocIds());
429
                $items = get_object_vars($items);
430
            } else {
431
                $items = [];
432
            }
433
            // get document instance to load further information
434
            $this->loadDocument((int) $documentItem['id']);
435
            if ($this->isDocMissing()) {
436
                // Quit without doing anything if required variables are not set.
437
                return null;
438
            }
439
            // set endpage for toc and subentry based on logid
440
            if (($piVars['addToBasket'] == 'subentry') or ($piVars['addToBasket'] == 'toc')) {
441
                $smLinks = $this->document->getCurrentDocument()->smLinks;
442
                $pageCounter = count($smLinks['l2p'][$piVars['logId']]);
443
                $documentItem['endpage'] = ($documentItem['startpage'] + $pageCounter) - 1;
444
            }
445
            // add whole document
446
            if ($piVars['addToBasket'] == 'list') {
447
                $documentItem['endpage'] = $this->document->getCurrentDocument()->numPages;
448
            }
449
            $arrayKey = $documentItem['id'] . '_' . $page;
450
            if (!empty($documentItem['startX'])) {
451
                $arrayKey .= '_' . $documentItem['startX'];
452
            }
453
            if (!empty($documentItem['endX'])) {
454
                $arrayKey .= '_' . $documentItem['endX'];
455
            }
456
            // do not add more than one identical object
457
            if (!in_array($arrayKey, $items)) {
458
                $items[$arrayKey] = $documentItem;
459
                // replace url param placeholder
460
                // TODO: Parameter #2 $replace of function str_replace expects array|string, int given.
461
                // @phpstan-ignore-next-line
462
                $pdfParams = str_replace("##startpage##", $documentItem['startpage'], $this->settings['pdfparams']);
463
                $pdfParams = str_replace("##docId##", $this->document->getRecordId(), $pdfParams);
464
                $pdfParams = str_replace("##startx##", $documentItem['startX'], $pdfParams);
465
                $pdfParams = str_replace("##starty##", $documentItem['startY'], $pdfParams);
466
                $pdfParams = str_replace("##endx##", $documentItem['endX'], $pdfParams);
467
                $pdfParams = str_replace("##endy##", $documentItem['endY'], $pdfParams);
468
                $pdfParams = str_replace("##rotation##", $documentItem['rotation'], $pdfParams);
469
                if ($documentItem['startpage'] != $documentItem['endpage']) {
470
                    $pdfParams = str_replace("##endpage##", $documentItem['endpage'], $pdfParams);
471
                } else {
472
                    // remove parameter endpage
473
                    $pdfParams = str_replace(",##endpage##", '', $pdfParams);
474
                }
475
                $pdfGenerateUrl = $this->settings['pdfgenerate'] . $pdfParams;
476
                if ($this->settings['pregeneration']) {
477
                    // send ajax request to webapp
478
                    $output .= '
479
     <script>
480
      $(document).ready(function(){
481
       $.ajax({
482
         url: "' . $pdfGenerateUrl . '",
483
       }).done(function() {
484
       });
485
      });
486
     </script>';
487
                }
488
            }
489
490
            $basket->setDocIds(json_encode($items));
491
            if ($basket->getUid() === null) {
492
                $this->basketRepository->add($basket);
493
            } else {
494
                $this->basketRepository->update($basket);
495
            }
496
        }
497
        $this->view->assign('pregenerateJs', $output);
498
499
        return $basket;
500
    }
501
502
    /**
503
     * Removes selected documents from basket
504
     *
505
     * @access protected
506
     *
507
     * @param array $piVars plugin variables
508
     * @param Basket $basket basket object
509
     *
510
     * @return Basket basket
511
     */
512
    protected function removeFromBasket(array $piVars, Basket $basket): Basket
513
    {
514
        if (!empty($basket->getDocIds())) {
515
            $items = json_decode($basket->getDocIds());
516
            $items = get_object_vars($items);
517
        }
518
        foreach ($piVars['selected'] as $value) {
519
            if (isset($value['id'])) {
520
                $arrayKey = $value['id'] . '_' . $value['startpage'];
521
                if (!empty($value['startX'])) {
522
                    $arrayKey .= '_' . $value['startX'];
523
                }
524
                if (!empty($value['endX'])) {
525
                    $arrayKey .= '_' . $value['endX'];
526
                }
527
                if (isset($items[$arrayKey])) {
528
                    unset($items[$arrayKey]);
529
                }
530
            }
531
        }
532
        if (empty($items)) {
533
            $update = '';
534
        } else {
535
            $update = json_encode($items);
536
        }
537
538
        $basket->setDocIds($update);
539
        $this->basketRepository->update($basket);
540
541
        return $basket;
542
    }
543
544
    /**
545
     * Send mail with pdf download url
546
     *
547
     * @access protected
548
     *
549
     * @return void
550
     */
551
    protected function sendMail(): void
552
    {
553
        // send mail
554
        $mailId = $this->requestData['mail_action'];
555
556
        $mailObject = $this->mailRepository->findByUid(intval($mailId))->getFirst();
557
558
        $mailText = htmlspecialchars(LocalizationUtility::translate('basket.mailBody', 'dlf')) . "\n";
0 ignored issues
show
Bug introduced by
It seems like TYPO3\CMS\Extbase\Utilit...asket.mailBody', 'dlf') can also be of type null; however, parameter $string of htmlspecialchars() 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 ignore-type  annotation

558
        $mailText = htmlspecialchars(/** @scrutinizer ignore-type */ LocalizationUtility::translate('basket.mailBody', 'dlf')) . "\n";
Loading history...
559
        $numberOfPages = 0;
560
        $pdfUrl = $this->settings['pdfdownload'];
561
        // prepare links
562
        foreach ($this->requestData['selected'] as $docValue) {
563
            if ($docValue['id']) {
564
                $explodeId = explode("_", $docValue['id']);
565
                $docData = $this->getDocumentData((int) $explodeId[0], $docValue);
566
                $pdfUrl .= $docData['urlParams'] . $this->settings['pdfparamseparator'];
567
                $pages = (abs(intval($docValue['startpage']) - intval($docValue['endpage'])));
568
                if ($pages === 0) {
569
                    $numberOfPages = $numberOfPages + 1;
570
                } else {
571
                    $numberOfPages = $numberOfPages + $pages;
572
                }
573
            }
574
        }
575
        // Remove leading/tailing pdfparamseperator
576
        $pdfUrl = trim($pdfUrl, $this->settings['pdfparamseparator']);
577
        $mailBody = $mailText . $pdfUrl;
578
        // Get hook objects.
579
        $hookObjects = Helper::getHookObjects('Classes/Controller/BasketController.php');
580
        // Hook for getting a customized mail body.
581
        foreach ($hookObjects as $hookObj) {
582
            if (method_exists($hookObj, 'customizeMailBody')) {
583
                $mailBody = $hookObj->customizeMailBody($mailText, $pdfUrl);
584
            }
585
        }
586
        $from = MailUtility::getSystemFrom();
587
        // send mail
588
        $mail = GeneralUtility::makeInstance(MailMessage::class);
589
        // Prepare and send the message
590
        $mail
591
            // subject
592
            ->setSubject(LocalizationUtility::translate('basket.mailSubject', 'dlf'))
593
            // Set the From address with an associative array
594
            ->setFrom($from)
595
            // Set the To addresses with an associative array
596
            ->setTo([$mailObject->getMail() => $mailObject->getName()])
597
            ->setBody($mailBody, 'text/html')
598
            ->send();
599
600
        // create entry for action log
601
        $newActionLog = GeneralUtility::makeInstance(ActionLog::class);
602
        $newActionLog->setFileName($pdfUrl);
603
        $newActionLog->setCountPages($numberOfPages);
604
        $newActionLog->setLabel('Mail: ' . $mailObject->getMail());
605
606
        if ($this->isUserLoggedIn()) {
607
            // internal user
608
            $newActionLog->setUserId($GLOBALS["TSFE"]->fe_user->user['uid']);
609
            $newActionLog->setName($GLOBALS["TSFE"]->fe_user->user['username']);
610
        } else {
611
            // external user
612
            $newActionLog->setUserId(0);
613
            $newActionLog->setName('n/a');
614
        }
615
616
        $this->actionLogRepository->add($newActionLog);
617
    }
618
619
    /**
620
     * Sends document information to an external printer (url)
621
     *
622
     * @access protected
623
     *
624
     * @return void
625
     */
626
    protected function printDocument(): void
627
    {
628
        $pdfUrl = $this->settings['pdfprint'];
629
        $numberOfPages = 0;
630
        foreach ($this->requestData['selected'] as $docId => $docValue) {
631
            if ($docValue['id']) {
632
                $docData = $this->getDocumentData((int) $docValue['id'], $docValue);
633
                $pdfUrl .= $docData['urlParams'] . $this->settings['pdfparamseparator'];
634
                $numberOfPages += $docData['pageNums'];
635
            }
636
        }
637
        // get printer data
638
        $printerId = $this->requestData['print_action'];
639
640
        // get id from db and send selected doc download link
641
        $printer = $this->printerRepository->findOneByUid($printerId);
0 ignored issues
show
Bug introduced by
The method findOneByUid() does not exist on Kitodo\Dlf\Domain\Repository\PrinterRepository. 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 ignore-call  annotation

641
        /** @scrutinizer ignore-call */ 
642
        $printer = $this->printerRepository->findOneByUid($printerId);
Loading history...
642
643
        // printer is selected
644
        if ($printer) {
645
            $pdfUrl = $printer->getPrint();
0 ignored issues
show
Bug introduced by
The method getPrint() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

645
            /** @scrutinizer ignore-call */ 
646
            $pdfUrl = $printer->getPrint();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
646
            $numberOfPages = 0;
647
            foreach ($this->requestData['selected'] as $docId => $docValue) {
648
                if ($docValue['id']) {
649
                    $explodeId = explode("_", $docId);
650
                    $docData = $this->getDocumentData((int) $explodeId[0], $docValue);
651
                    $pdfUrl .= $docData['urlParams'] . $this->settings['pdfparamseparator'];
652
                    $numberOfPages += $docData['pageNums'];
653
                }
654
            }
655
            $pdfUrl = trim($pdfUrl, $this->settings['pdfparamseparator']);
656
        }
657
658
        $actionLog = GeneralUtility::makeInstance(ActionLog::class);
659
        // protocol
660
        $actionLog->setPid($this->settings['storagePid']);
661
        $actionLog->setFileName($pdfUrl);
662
        $actionLog->setCountPages($numberOfPages);
663
664
        if ($this->isUserLoggedIn()) {
665
            // internal user
666
            $actionLog->setUserId($GLOBALS["TSFE"]->fe_user->user['uid']);
667
            $actionLog->setName($GLOBALS["TSFE"]->fe_user->user['username']);
668
            $actionLog->setLabel('Print: ' . $printer->getLabel());
0 ignored issues
show
Bug introduced by
The method getLabel() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

668
            $actionLog->setLabel('Print: ' . $printer->/** @scrutinizer ignore-call */ getLabel());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
669
        } else {
670
            // external user
671
            $actionLog->setUserId(0);
672
            $actionLog->setName('n/a');
673
            $actionLog->setLabel('Print: ' . $printer->getLabel());
674
        }
675
        // add action to protocol
676
        $this->actionLogRepository->add($actionLog);
677
678
        $this->redirectToUri($pdfUrl);
679
    }
680
681
    /**
682
     * Return true if the user is logged in.
683
     * 
684
     * @access protected
685
     * 
686
     * @return bool whether the user is logged in
687
     */
688
    protected function isUserLoggedIn(): bool
689
    {
690
        $context = GeneralUtility::makeInstance(Context::class);
691
        return $context->getPropertyFromAspect('frontend.user', 'isLoggedIn');
692
    }
693
}
694