Completed
Pull Request — master (#278)
by Pascale
03:06
created

AbstractController::calculatePluginHmac()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 0
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 HDNET\Calendarize\Utility\HelperUtility;
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\Object\ObjectManager;
20
use TYPO3\CMS\Extbase\Security\Cryptography\HashService;
21
use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
22
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
23
24
/**
25
 * Abstract controller.
26
 */
27
abstract class AbstractController extends ActionController
28
{
29
    /**
30
     * The index repository.
31
     *
32
     * @var \HDNET\Calendarize\Domain\Repository\IndexRepository
33
     */
34
    protected $indexRepository;
35
36
    public function injectIndexRepository(IndexRepository $indexRepository)
37
    {
38
        $this->indexRepository = $indexRepository;
39
    }
40
41
    /**
42
     * The feed formats and content types.
43
     *
44
     * @var array
45
     */
46
    protected $feedFormats = [
47
        'ics' => 'text/calendar',
48
        'xml' => 'application/xml',
49
        'atom' => 'application/rss+xml',
50
    ];
51
52
    /**
53
     * Inject the configuration manager.
54
     *
55
     * @param ConfigurationManagerInterface $configurationManager
56
     */
57
    public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
58
    {
59
        $this->configurationManager = $configurationManager;
60
61
        $this->settings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
62
63
        $objectManager = new ObjectManager();
64
        $pluginConfigurationService = $objectManager->get(PluginConfigurationService::class);
65
        $this->settings = $pluginConfigurationService->respectPluginConfiguration((array) $this->settings);
66
    }
67
68
    /**
69
     * Init all actions.
70
     */
71
    public function initializeAction()
72
    {
73
        parent::initializeAction();
74
        AbstractBookingRequest::setConfigurations(GeneralUtility::trimExplode(',', $this->settings['configuration']));
75
    }
76
77
    /**
78
     * Calls the specified action method and passes the arguments.
79
     *
80
     * If the action returns a string, it is appended to the content in the
81
     * response object. If the action doesn't return anything and a valid
82
     * view exists, the view is rendered automatically.
83
     *
84
     * @api
85
     */
86
    protected function callActionMethod()
87
    {
88
        parent::callActionMethod();
89
        if (isset($this->feedFormats[$this->request->getFormat()])) {
90
            $this->sendHeaderAndFilename($this->feedFormats[$this->request->getFormat()], $this->request->getFormat());
91
            if ($this->request->hasArgument('hmac')) {
92
                $hmac = $this->request->getArgument('hmac');
93
                if ($this->validatePluginHmac($hmac)) {
94
                    $this->sendHeaderAndFilename($this->feedFormats[$this->request->getFormat()], $this->request->getFormat());
95
                }
96
97
                return;
98
            }
99
            $this->sendHeaderAndFilename($this->feedFormats[$this->request->getFormat()], $this->request->getFormat());
100
        }
101
    }
102
103
    /**
104
     * Send the content type header and the right file extension in front of the content.
105
     *
106
     * @param $contentType
107
     * @param $fileExtension
108
     */
109
    protected function sendHeaderAndFilename($contentType, $fileExtension)
110
    {
111
        $testMode = (bool) $this->settings['feed']['debugMode'];
112
        if ($testMode) {
113
            \header('Content-Type: text/plain; charset=utf-8');
114
        } else {
115
            \header('Content-Type: ' . $contentType . '; charset=utf-8');
116
            \header('Content-Disposition: inline; filename=calendar.' . $fileExtension);
117
        }
118
        echo $this->response->getContent();
119
        HttpUtility::setResponseCodeAndExit(HttpUtility::HTTP_STATUS_200);
120
    }
121
122
    /**
123
     * Extend the view by the slot class and name and assign the variable to the view.
124
     *
125
     * @param array  $variables
126
     * @param string $signalClassName
127
     * @param string $signalName
128
     */
129
    protected function slotExtendedAssignMultiple(array $variables, $signalClassName, $signalName)
130
    {
131
        // use this variable in your extension to add more custom variables
132
        $variables['extended'] = [];
133
        $variables['extended']['pluginHmac'] = $this->calculatePluginHmac();
134
        $variables['settings'] = $this->settings;
135
        $variables['contentObject'] = $this->configurationManager->getContentObject()->data;
136
137
        $dispatcher = $this->objectManager->get(Dispatcher::class);
138
        $variables = $dispatcher->dispatch($signalClassName, $signalName, $variables);
139
140
        $this->view->assignMultiple($variables);
141
    }
142
143
    /**
144
     * Return the controllerName, pluginName and actionName.
145
     *
146
     * @return string
147
     */
148
    protected function getStringForPluginHmac(): string
149
    {
150
        $actionMethodName = \ucfirst($this->request->getControllerActionName());
151
        $pluginName = $this->request->getPluginName();
152
        $controllerName = $this->request->getControllerName();
153
154
        return $controllerName . $pluginName . $actionMethodName;
155
    }
156
157
    /**
158
     * Calculate the plugin Hmac.
159
     *
160
     * @see \TYPO3\CMS\Extbase\Security\Cryptography\HashService::generateHmac()
161
     *
162
     * @return string $hmac
163
     */
164
    protected function calculatePluginHmac()
165
    {
166
        $string = $this->getStringForPluginHmac();
167
168
        /** @var HashService $hashService */
169
        $hashService = HelperUtility::create(HashService::class);
170
        $hmac = $hashService->generateHmac($string);
171
172
        return $hmac;
173
    }
174
175
    /**
176
     * \TYPO3\CMS\Extbase\Security\Cryptography\HashService::validateHmac().
177
     *
178
     * @param string $hmac
179
     *
180
     * @return bool
181
     */
182
    protected function validatePluginHmac(string $hmac): bool
183
    {
184
        $string = $this->getStringForPluginHmac();
185
186
        /** @var HashService $hashService */
187
        $hashService = HelperUtility::create(HashService::class);
188
189
        return $hashService->validateHmac($string, $hmac);
190
    }
191
192
    /**
193
     * Check if the static template is included.
194
     */
195
    protected function checkStaticTemplateIsIncluded()
196
    {
197
        if (!isset($this->settings['dateFormat'])) {
198
            $this->addFlashMessage(
199
                '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.',
200
                'Configuration Error',
201
                FlashMessage::ERROR
202
            );
203
        }
204
    }
205
206
    /**
207
     * Change the page title.
208
     *
209
     * @param string $title
210
     */
211
    protected function changePageTitle($title)
212
    {
213
        /** @var TypoScriptFrontendController $frontendController */
214
        $frontendController = $GLOBALS['TSFE'];
215
        $frontendController->page['title'] = $title;
216
        $frontendController->indexedDocTitle = $title;
217
    }
218
}
219