Completed
Push — master ( 70dfe1...a97a1c )
by Torben
04:18
created

AdministrationController::getCreateNewRecordUri()   A

Complexity

Conditions 5
Paths 2

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 0
cp 0
rs 9.3554
c 0
b 0
f 0
cc 5
nc 2
nop 1
crap 30
1
<?php
2
3
/*
4
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
5
 *
6
 * For the full copyright and license information, please read the
7
 * LICENSE.txt file that was distributed with this source code.
8
 */
9
10
namespace DERHANSEN\SfEventMgt\Controller;
11
12
use DERHANSEN\SfEventMgt\Domain\Model\Dto\EventDemand;
13
use DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand;
14
use DERHANSEN\SfEventMgt\Domain\Model\Event;
15
use DERHANSEN\SfEventMgt\Service;
16
use TYPO3\CMS\Backend\Routing\UriBuilder;
17
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
18
use TYPO3\CMS\Backend\Utility\BackendUtility;
19
use TYPO3\CMS\Backend\View\BackendTemplateView;
20
use TYPO3\CMS\Core\Imaging\Icon;
21
use TYPO3\CMS\Core\Imaging\IconFactory;
22
use TYPO3\CMS\Core\Localization\LanguageService;
23
use TYPO3\CMS\Core\Messaging\FlashMessage;
24
use TYPO3\CMS\Core\Utility\GeneralUtility;
25
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
26
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder as ExtbaseUriBuilder;
27
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
28
29
/**
30
 * AdministrationController
31
 *
32
 * Several parts are heavily inspired by ext:news from Georg Ringer
33
 *
34
 * @author Torben Hansen <[email protected]>
35
 */
36
class AdministrationController extends AbstractController
37
{
38
    const LANG_FILE = 'LLL:EXT:sf_event_mgt/Resources/Private/Language/locallang_be.xlf:';
39
40
    /**
41
     * Backend Template Container
42
     *
43
     * @var string
44
     */
45
    protected $defaultViewObjectName = \TYPO3\CMS\Backend\View\BackendTemplateView::class;
46
47
    /**
48
     * CustomNotificationLogRepository
49
     *
50
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\CustomNotificationLogRepository
51
     */
52
    protected $customNotificationLogRepository;
53
54
    /**
55
     * ExportService
56
     *
57
     * @var \DERHANSEN\SfEventMgt\Service\ExportService
58
     */
59
    protected $exportService;
60
61
    /**
62
     * SettingsService
63
     *
64
     * @var \DERHANSEN\SfEventMgt\Service\SettingsService
65
     */
66
    protected $settingsService;
67
68
    /**
69
     * Backend User Session Service
70
     *
71
     * @var \DERHANSEN\SfEventMgt\Service\BeUserSessionService
72
     */
73
    protected $beUserSessionService;
74
75
    /**
76
     * @var \DERHANSEN\SfEventMgt\Service\MaintenanceService
77
     */
78
    protected $maintenanceService;
79
80
    /**
81
     * The current page uid
82
     *
83
     * @var int
84
     */
85
    protected $pid = 0;
86
87
    /**
88
     * BackendTemplateContainer
89
     *
90
     * @var BackendTemplateView
91 2
     */
92
    protected $view;
93 2
94 2
    /**
95
     * @var IconFactory
96
     */
97
    protected $iconFactory;
98
99
    /**
100
     * DI for $customNotificationLogRepository
101 4
     *
102
     * @param \DERHANSEN\SfEventMgt\Domain\Repository\CustomNotificationLogRepository $customNotificationLogRepository
103 4
     */
104 2
    public function injectCustomNotificationLogRepository(
105 2
        \DERHANSEN\SfEventMgt\Domain\Repository\CustomNotificationLogRepository $customNotificationLogRepository
106 4
    ) {
107 4
        $this->customNotificationLogRepository = $customNotificationLogRepository;
108 4
    }
109 4
110 4
    /**
111 4
     * DI for $exportService
112 4
     *
113 4
     * @param Service\ExportService $exportService
114 4
     */
115 4
    public function injectExportService(\DERHANSEN\SfEventMgt\Service\ExportService $exportService)
116 4
    {
117 4
        $this->exportService = $exportService;
118 4
    }
119 4
120 4
    /**
121
     * DI for $settingsService
122
     *
123
     * @param Service\SettingsService $settingsService
124
     */
125
    public function injectSettingsService(\DERHANSEN\SfEventMgt\Service\SettingsService $settingsService)
126
    {
127
        $this->settingsService = $settingsService;
128
    }
129
130 8
    /**
131
     * DI for $beUserSessionService
132
     *
133 8
     * @param Service\BeUserSessionService $beUserSessionService
134
     */
135 8
    public function injectBeUserSessionService(\DERHANSEN\SfEventMgt\Service\BeUserSessionService $beUserSessionService)
136 6
    {
137 6
        $this->beUserSessionService = $beUserSessionService;
138 8
    }
139
140 8
    /**
141 4
     * DI for $iconFactory
142 4
     *
143
     * @param IconFactory $iconFactory
144 8
     */
145 2
    public function injectIconFactory(IconFactory $iconFactory)
146 2
    {
147 2
        $this->iconFactory = $iconFactory;
148 2
    }
149
150 8
    /**
151 8
     * @param Service\MaintenanceService $maintenanceService
152 8
     */
153 8
    public function injectMaintenanceService(\DERHANSEN\SfEventMgt\Service\MaintenanceService $maintenanceService)
154
    {
155
        $this->maintenanceService = $maintenanceService;
156
    }
157
158
    /**
159
     * Set up the doc header properly here
160
     *
161
     * @param ViewInterface $view
162 2
     */
163
    protected function initializeView(ViewInterface $view)
164 2
    {
165 2
        /** @var BackendTemplateView $view */
166
        parent::initializeView($view);
167
        if ($this->actionMethodName === 'listAction'
168
            || $this->actionMethodName === 'indexNotifyAction'
169
            || $this->actionMethodName === 'settingsErrorAction'
170
        ) {
171
            $this->registerDocHeaderButtons();
172
173 2
            $pageRenderer = $this->view->getModuleTemplate()->getPageRenderer();
174
            $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DateTimePicker');
175 2
176 2
            $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ?
177 2
                ['MM-DD-YYYY', 'HH:mm MM-DD-YYYY'] :
178
                ['DD-MM-YYYY', 'HH:mm DD-MM-YYYY'];
179
            $pageRenderer->addInlineSetting('DateTimePicker', 'DateFormat', $dateFormat);
180
181
            $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
182
            if ($view instanceof BackendTemplateView) {
183
                $view->getModuleTemplate()->getPageRenderer()->addCssFile(
184
                    'EXT:sf_event_mgt/Resources/Public/Css/administration.css'
185
                );
186 2
            }
187
        }
188 2
    }
189 2
190 2
    /**
191 2
     * Register docHeaderButtons
192 2
     */
193 2
    protected function registerDocHeaderButtons()
194 2
    {
195 2
        $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
196
197
        $uriBuilder = $this->objectManager->get(ExtbaseUriBuilder::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
198
        $uriBuilder->setRequest($this->request);
199
200
        if ($this->request->getControllerActionName() === 'list') {
201
            $buttons = [
202
                [
203
                    'label' => 'administration.newEvent',
204
                    'link' => $this->getCreateNewRecordUri('tx_sfeventmgt_domain_model_event'),
205 2
                    'icon' => 'ext-sfeventmgt-event',
206
                    'group' => 1
207 2
                ],
208 2
                [
209 2
                    'label' => 'administration.newLocation',
210 2
                    'link' => $this->getCreateNewRecordUri('tx_sfeventmgt_domain_model_location'),
211 2
                    'icon' => 'ext-sfeventmgt-location',
212
                    'group' => 1
213 2
                ],
214 2
                [
215 2
                    'label' => 'administration.newOrganisator',
216
                    'link' => $this->getCreateNewRecordUri('tx_sfeventmgt_domain_model_organisator'),
217
                    'icon' => 'ext-sfeventmgt-organisator',
218
                    'group' => 1
219
                ],
220
                [
221
                    'label' => 'administration.newSpeaker',
222
                    'link' => $this->getCreateNewRecordUri('tx_sfeventmgt_domain_model_speaker'),
223
                    'icon' => 'ext-sfeventmgt-speaker',
224
                    'group' => 1
225
                ],
226
                [
227
                    'label' => 'administration.handleExpiredRegistrations',
228
                    'link' => $uriBuilder->reset()->setRequest($this->request)
229
                        ->uriFor('handleExpiredRegistrations', [], 'Administration'),
230
                    'icon' => 'ext-sfeventmgt-action-handle-expired',
231
                    'group' => 2,
232
                ]
233
            ];
234
            foreach ($buttons as $key => $tableConfiguration) {
235
                $title = $this->getLanguageService()->sL(self::LANG_FILE . $tableConfiguration['label']);
236
                $icon = $this->iconFactory->getIcon($tableConfiguration['icon'], Icon::SIZE_SMALL);
237
                $viewButton = $buttonBar->makeLinkButton()
238
                    ->setHref($tableConfiguration['link'])
239
                    ->setDataAttributes([
240
                        'toggle' => 'tooltip',
241
                        'placement' => 'bottom',
242
                        'title' => $title
243
                        ])
244
                    ->setTitle($title)
245
                    ->setIcon($icon);
246
                $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, $tableConfiguration['group']);
247
            }
248
        }
249
    }
250
251
    /**
252
     * Returns the create new record URL for the given table
253
     *
254
     * @param $table
255
     * @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
256
     * @return string
257
     */
258
    private function getCreateNewRecordUri($table): string
259
    {
260
        $pid = $this->pid;
261
        $tsConfig = BackendUtility::getPagesTSconfig(0);
262
        if ($pid === 0 && isset($tsConfig['defaultPid.'])
263
            && is_array($tsConfig['defaultPid.'])
264
            && isset($tsConfig['defaultPid.'][$table])
265
        ) {
266
            $pid = (int)$tsConfig['defaultPid.'][$table];
267
        }
268
269
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
270
271
        return $uriBuilder->buildUriFromRoute('record_edit', [
272
            'edit[' . $table . '][' . $pid . ']' => 'new',
273
            'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
274
        ]);
275
    }
276
277
    /**
278
     * Initialize action
279
     */
280
    public function initializeAction()
281
    {
282
        $this->pid = (int)\TYPO3\CMS\Core\Utility\GeneralUtility::_GET('id');
283
    }
284
285
    /**
286
     * Set date format for fields startDate and endDate
287
     */
288
    public function initializeListAction()
289
    {
290
        if ($this->settings === null || empty($this->settings)) {
291
            $this->redirect('settingsError');
292
        }
293
        $this->arguments->getArgument('searchDemand')
294
            ->getPropertyMappingConfiguration()->forProperty('startDate')
295
            ->setTypeConverterOption(
296
                DateTimeConverter::class,
297
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
298
                $this->settings['search']['dateFormat']
299
            );
300
        $this->arguments->getArgument('searchDemand')
301
            ->getPropertyMappingConfiguration()->forProperty('endDate')
302
            ->setTypeConverterOption(
303
                DateTimeConverter::class,
304
                DateTimeConverter::CONFIGURATION_DATE_FORMAT,
305
                $this->settings['search']['dateFormat']
306
            );
307
    }
308
309
    /**
310
     * List action for backend module
311
     *
312
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Dto\SearchDemand $searchDemand SearchDemand
313
     * @param array $overwriteDemand OverwriteDemand
314
     */
315
    public function listAction(SearchDemand $searchDemand = null, array $overwriteDemand = [])
316
    {
317
        /** @var EventDemand $eventDemand */
318
        $eventDemand = $this->objectManager->get(EventDemand::class);
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Extbase\Object...ManagerInterface::get() has been deprecated with message: since TYPO3 10.4, will be removed in version 12.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
319
        $eventDemand = $this->overwriteEventDemandObject($eventDemand, $overwriteDemand);
320
        $eventDemand->setOrderFieldAllowed($this->settings['orderFieldAllowed']);
321
322
        if ($searchDemand !== null) {
323
            $searchDemand->setFields($this->settings['search']['fields']);
324
325
            $sessionData = [];
326
            $sessionData['searchDemand'] = $searchDemand;
327
            $sessionData['overwriteDemand'] = $overwriteDemand;
328
            $this->beUserSessionService->saveSessionData($sessionData);
329
        } else {
330
            // Try to restore search demand from Session
331
            $searchDemand = $this->beUserSessionService->getSessionDataByKey('searchDemand');
332
            $overwriteDemand = $this->beUserSessionService->getSessionDataByKey('overwriteDemand');
333
        }
334
335
        $eventDemand->setSearchDemand($searchDemand);
336
        $eventDemand->setStoragePage($this->pid);
337
338
        $this->view->assignMultiple([
339
            'pid' => $this->pid,
340
            'events' => $this->eventRepository->findDemanded($eventDemand),
341
            'searchDemand' => $searchDemand,
342
            'orderByFields' => $this->getOrderByFields(),
343
            'orderDirections' => $this->getOrderDirections(),
344
            'overwriteDemand' => $overwriteDemand,
345
        ]);
346
    }
347
348
    /**
349
     * Export registrations for a given event
350
     *
351
     * @param int $eventUid Event UID
352
     */
353
    public function exportAction($eventUid)
354
    {
355
        $this->exportService->downloadRegistrationsCsv($eventUid, $this->settings['csvExport']);
356
        exit();
357
    }
358
359
    /**
360
     * Handles expired registrations
361
     */
362
    public function handleExpiredRegistrationsAction()
363
    {
364
        $delete = (bool)$this->settings['registration']['deleteExpiredRegistrations'];
365
        $this->maintenanceService->handleExpiredRegistrations($delete);
366
367
        $this->addFlashMessage(
368
            $this->getLanguageService()->sL(self::LANG_FILE . 'administration.message-1.content'),
369
            $this->getLanguageService()->sL(self::LANG_FILE . 'administration.message-1.title'),
370
            FlashMessage::OK
371
        );
372
373
        $this->redirect('list');
374
    }
375
376
    /**
377
     * The index notify action
378
     *
379
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
380
     */
381
    public function indexNotifyAction(Event $event)
382
    {
383
        $customNotifications = $this->settingsService->getCustomNotifications($this->settings);
384
        $logEntries = $this->customNotificationLogRepository->findByEvent($event);
0 ignored issues
show
Documentation Bug introduced by
The method findByEvent does not exist on object<DERHANSEN\SfEvent...ificationLogRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
385
        $this->view->assignMultiple([
386
            'event' => $event,
387
            'customNotifications' => $customNotifications,
388
            'logEntries' => $logEntries,
389
        ]);
390
    }
391
392
    /**
393
     * Notify action
394
     *
395
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Event $event Event
396
     * @param string $customNotification CustomNotification
397
     */
398
    public function notifyAction(Event $event, $customNotification)
399
    {
400
        $customNotifications = $this->settingsService->getCustomNotifications($this->settings);
401
        $result = $this->notificationService->sendCustomNotification($event, $customNotification, $this->settings);
402
        $this->notificationService->createCustomNotificationLogentry(
403
            $event,
404
            $customNotifications[$customNotification],
405
            $result
406
        );
407
        $this->addFlashMessage(
408
            $this->getLanguageService()->sL(self::LANG_FILE . 'administration.message-2.content'),
409
            $this->getLanguageService()->sL(self::LANG_FILE . 'administration.message-2.title'),
410
            FlashMessage::OK
411
        );
412
        $this->redirect('list');
413
    }
414
415
    /**
416
     * Shows the settings error view
417
     */
418
    public function settingsErrorAction()
419
    {
420
    }
421
422
    /**
423
     * Suppress default validation messages
424
     *
425
     * @return bool
426
     */
427
    protected function getErrorFlashMessage()
428
    {
429
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method TYPO3\CMS\Extbase\Mvc\Co...r::getErrorFlashMessage of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
430
    }
431
432
    /**
433
     * Returns the LanguageService
434
     *
435
     * @return LanguageService
436
     */
437
    protected function getLanguageService(): LanguageService
438
    {
439
        return $GLOBALS['LANG'];
440
    }
441
442
    /**
443
     * Returns an array with possible order directions
444
     *
445
     * @return array
446
     */
447
    public function getOrderDirections()
448
    {
449
        return [
450
            'asc' => $this->getLanguageService()->sL(self::LANG_FILE . 'administration.sortOrder.asc'),
451
            'desc' => $this->getLanguageService()->sL(self::LANG_FILE . 'administration.sortOrder.desc')
452
        ];
453
    }
454
455
    /**
456
     * Returns an array with possible orderBy fields
457
     *
458
     * @return array
459
     */
460
    public function getOrderByFields()
461
    {
462
        return [
463
            'title' => $this->getLanguageService()->sL(self::LANG_FILE . 'administration.orderBy.title'),
464
            'startdate' => $this->getLanguageService()->sL(self::LANG_FILE . 'administration.orderBy.startdate'),
465
            'enddate' => $this->getLanguageService()->sL(self::LANG_FILE . 'administration.orderBy.enddate')
466
        ];
467
    }
468
}
469