Completed
Push — master ( b7833b...bef2f6 )
by Tim
01:59
created

isDateOutOfTypoScriptConfiguration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
/**
4
 * Abstract controller.
5
 */
6
declare(strict_types=1);
7
8
namespace HDNET\Calendarize\Controller;
9
10
use HDNET\Calendarize\Domain\Repository\IndexRepository;
11
use HDNET\Calendarize\Property\TypeConverter\AbstractBookingRequest;
12
use HDNET\Calendarize\Service\PluginConfigurationService;
13
use Psr\Http\Message\ResponseInterface;
14
use TYPO3\CMS\Core\Messaging\FlashMessage;
15
use TYPO3\CMS\Core\Utility\GeneralUtility;
16
use TYPO3\CMS\Core\Utility\HttpUtility;
17
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
18
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
19
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
20
use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
21
use TYPO3\CMS\Frontend\Controller\ErrorController;
22
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
23
use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons;
24
25
/**
26
 * Abstract controller.
27
 */
28
abstract class AbstractController extends ActionController
29
{
30
    /**
31
     * The index repository.
32
     *
33
     * @var \HDNET\Calendarize\Domain\Repository\IndexRepository
34
     */
35
    protected $indexRepository;
36
37
    /**
38
     * The feed formats and content types.
39
     *
40
     * @var array
41
     */
42
    protected $feedFormats = [
43
        'ics' => 'text/calendar',
44
        'xml' => 'application/xml',
45
        'atom' => 'application/rss+xml',
46
    ];
47
48
    /**
49
     * Inject index repository.
50
     *
51
     * @param \HDNET\Calendarize\Domain\Repository\IndexRepository $indexRepository
52
     */
53
    public function injectIndexRepository(IndexRepository $indexRepository)
54
    {
55
        $this->indexRepository = $indexRepository;
56
    }
57
58
    /**
59
     * Inject the configuration manager.
60
     *
61
     * @param ConfigurationManagerInterface $configurationManager
62
     */
63
    public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
64
    {
65
        $this->configurationManager = $configurationManager;
66
67
        $this->settings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
68
69
        $pluginConfigurationService = GeneralUtility::makeInstance(PluginConfigurationService::class);
70
        $this->settings = $pluginConfigurationService->respectPluginConfiguration((array) $this->settings);
71
    }
72
73
    /**
74
     * Init all actions.
75
     */
76
    public function initializeAction()
77
    {
78
        parent::initializeAction();
79
        AbstractBookingRequest::setConfigurations(GeneralUtility::trimExplode(',', $this->settings['configuration']));
80
    }
81
82
    /**
83
     * Calls the specified action method and passes the arguments.
84
     *
85
     * If the action returns a string, it is appended to the content in the
86
     * response object. If the action doesn't return anything and a valid
87
     * view exists, the view is rendered automatically.
88
     *
89
     * @api
90
     */
91
    protected function callActionMethod()
92
    {
93
        parent::callActionMethod();
94
        if (isset($this->feedFormats[$this->request->getFormat()])) {
95
            $this->sendHeaderAndFilename($this->feedFormats[$this->request->getFormat()], $this->request->getFormat());
96
            if ($this->request->hasArgument('hmac')) {
97
                $hmac = $this->request->getArgument('hmac');
98
                if ($this->validatePluginHmac($hmac)) {
0 ignored issues
show
Bug introduced by
It seems like $hmac defined by $this->request->getArgument('hmac') on line 97 can also be of type array; however, HDNET\Calendarize\Contro...r::validatePluginHmac() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
99
                    $this->sendHeaderAndFilename($this->feedFormats[$this->request->getFormat()], $this->request->getFormat());
100
                }
101
102
                return;
103
            }
104
            $this->sendHeaderAndFilename($this->feedFormats[$this->request->getFormat()], $this->request->getFormat());
105
        }
106
    }
107
108
    /**
109
     * Send the content type header and the right file extension in front of the content.
110
     *
111
     * @param $contentType
112
     * @param $fileExtension
113
     */
114
    protected function sendHeaderAndFilename($contentType, $fileExtension)
115
    {
116
        $testMode = (bool) $this->settings['feed']['debugMode'];
117
        if ($testMode) {
118
            header('Content-Type: text/plain; charset=utf-8');
119
        } else {
120
            header('Content-Type: ' . $contentType . '; charset=utf-8');
121
            header('Content-Disposition: inline; filename=calendar.' . $fileExtension);
122
        }
123
        switch ($this->request->getFormat()) {
124
            case 'ics':
125
                // Use CRLF, see https://tools.ietf.org/html/rfc5545#section-3.1
126
                echo str_replace("\n", "\r\n", $this->response->getContent());
127
                break;
128
            default:
129
                echo $this->response->getContent();
130
                break;
131
        }
132
        HttpUtility::setResponseCodeAndExit(HttpUtility::HTTP_STATUS_200);
133
    }
134
135
    /**
136
     * Extend the view by the slot class and name and assign the variable to the view.
137
     *
138
     * @param array $variables
139
     * @param string $signalClassName
140
     * @param string $signalName
141
     */
142
    protected function slotExtendedAssignMultiple(array $variables, $signalClassName, $signalName)
143
    {
144
        // use this variable in your extension to add more custom variables
145
        $variables['extended'] = [];
146
        $variables['extended']['pluginHmac'] = $this->calculatePluginHmac();
147
        $variables['settings'] = $this->settings;
148
        $variables['contentObject'] = $this->configurationManager->getContentObject()->data;
149
150
        $dispatcher = $this->objectManager->get(Dispatcher::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...
151
        $variables = $dispatcher->dispatch($signalClassName, $signalName, $variables);
152
153
        $this->view->assignMultiple($variables);
154
    }
155
156
    /**
157
     * Return the controllerName, pluginName and actionName.
158
     *
159
     * @return string
160
     */
161
    protected function getStringForPluginHmac(): string
162
    {
163
        $actionMethodName = ucfirst($this->request->getControllerActionName());
164
        $pluginName = $this->request->getPluginName();
165
        $controllerName = $this->request->getControllerName();
166
167
        return $controllerName . $pluginName . $actionMethodName;
168
    }
169
170
    /**
171
     * Calculate the plugin Hmac.
172
     *
173
     * @return string $hmac
174
     * @see \TYPO3\CMS\Extbase\Security\Cryptography\HashService::generateHmac()
175
     *
176
     */
177
    protected function calculatePluginHmac()
178
    {
179
        $string = $this->getStringForPluginHmac();
180
181
        $hashService = GeneralUtility::makeInstance(HashService::class);
182
183
        return $hashService->generateHmac($string);
184
    }
185
186
    /**
187
     * \TYPO3\CMS\Extbase\Security\Cryptography\HashService::validateHmac().
188
     *
189
     * @param string $hmac
190
     *
191
     * @return bool
192
     */
193
    protected function validatePluginHmac(string $hmac): bool
194
    {
195
        $string = $this->getStringForPluginHmac();
196
197
        /** @var HashService $hashService */
198
        $hashService = GeneralUtility::makeInstance(HashService::class);
199
200
        return $hashService->validateHmac($string, $hmac);
201
    }
202
203
    /**
204
     * Check if the static template is included.
205
     */
206
    protected function checkStaticTemplateIsIncluded()
207
    {
208
        if (!isset($this->settings['dateFormat'])) {
209
            $this->addFlashMessage(
210
                'Basic configuration settings are missing. It seems, that the Static Extension TypoScript is not loaded to your TypoScript configuration. Please add the calendarize TS to your TS settings.',
211
                'Configuration Error',
212
                FlashMessage::ERROR
213
            );
214
        }
215
    }
216
217
    /**
218
     * Change the page title.
219
     *
220
     * @param string $title
221
     */
222
    protected function changePageTitle($title)
223
    {
224
        /** @var TypoScriptFrontendController $frontendController */
225
        $frontendController = $GLOBALS['TSFE'];
226
        $frontendController->page['title'] = $title;
227
        $frontendController->indexedDocTitle = $title;
228
    }
229
230
    /**
231
     * Add cache tags.
232
     *
233
     * @param array $tags
234
     */
235
    protected function addCacheTags(array $tags)
236
    {
237
        if ($GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {
238
            $GLOBALS['TSFE']->addCacheTags($tags);
239
        }
240
    }
241
242
    protected function isDateOutOfTypoScriptConfiguration(\DateTime $dateTime): bool
243
    {
244
        $prev = new \DateTime($this->settings['dateLimitBrowserPrev']);
245
        $next = new \DateTime($this->settings['dateLimitBrowserNext']);
246
        return ($prev > $dateTime || $next < $dateTime);
247
    }
248
249
    protected function return404Page(): ResponseInterface
250
    {
251
        return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
252
            $GLOBALS['TYPO3_REQUEST'],
253
            'The requested page does not exist',
254
            ['code' => PageAccessFailureReasons::PAGE_NOT_FOUND]
255
        );
256
    }
257
}
258