Passed
Push — feature/typo3v10_fixFeRenderin... ( b3b8a1 )
by
unknown
04:12
created

Loader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
c 0
b 0
f 0
nc 1
nop 6
dl 0
loc 14
rs 10
1
<?php
2
namespace Aoe\Restler\System\TYPO3;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2021 AOE GmbH <[email protected]>
8
 *
9
 *  All rights reserved
10
 *
11
 *  This script is part of the TYPO3 project. The TYPO3 project is
12
 *  free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 3 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  The GNU General Public License can be found at
18
 *  http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 *  This script is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
use Psr\Http\Message\ServerRequestInterface;
29
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
30
use TYPO3\CMS\Core\Http\Response;
31
use TYPO3\CMS\Core\Routing\PageArguments;
32
use TYPO3\CMS\Core\SingletonInterface;
33
use TYPO3\CMS\Core\Site\SiteFinder;
34
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
35
use TYPO3\CMS\Core\TypoScript\TemplateService;
36
use TYPO3\CMS\Core\Utility\GeneralUtility;
37
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
38
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
39
use TYPO3\CMS\Frontend\Http\RequestHandler;
40
use TYPO3\CMS\Frontend\Middleware\BackendUserAuthenticator;
41
use TYPO3\CMS\Frontend\Middleware\FrontendUserAuthenticator;
42
use TYPO3\CMS\Frontend\Middleware\PrepareTypoScriptFrontendRendering;
43
use TYPO3\CMS\Frontend\Middleware\TypoScriptFrontendInitialization;
44
use LogicException;
45
46
/**
47
 * @package Restler
48
 */
49
class Loader implements SingletonInterface
50
{
51
    /**
52
     * @var BackendUserAuthenticator
53
     */
54
    private $backendUserAuthenticator;
55
56
    /**
57
     * @var FrontendUserAuthenticator
58
     */
59
    private $frontendUserAuthenticator;
60
61
    /**
62
     * @var MockedRequestHandler
63
     */
64
    private $mockedRequestHandler;
65
66
    /**
67
     * @var RequestHandler
68
     */
69
    private $requestHandler;
70
71
    /**
72
     * @var TimeTracker
73
     */
74
    protected $timeTracker;
75
76
    /**
77
     * @var TypoScriptFrontendInitialization
78
     */
79
    private $typoScriptFrontendInitialization;
80
81
    /**
82
     * @param BackendUserAuthenticator         $backendUserAuthenticator
83
     * @param FrontendUserAuthenticator        $frontendUserAuthenticator
84
     * @param MockedRequestHandler             $mockedRequestHandler
85
     * @param RequestHandler                   $requestHandler
86
     * @param TimeTracker                      $timeTracker
87
     * @param TypoScriptFrontendInitialization $typoScriptFrontendInitialization
88
     */
89
    public function __construct(
90
        BackendUserAuthenticator $backendUserAuthenticator,
91
        FrontendUserAuthenticator $frontendUserAuthenticator,
92
        MockedRequestHandler $mockedRequestHandler,
93
        RequestHandler $requestHandler,
94
        TimeTracker $timeTracker,
95
        TypoScriptFrontendInitialization $typoScriptFrontendInitialization
96
    ) {
97
        $this->backendUserAuthenticator = $backendUserAuthenticator;
98
        $this->frontendUserAuthenticator = $frontendUserAuthenticator;
99
        $this->mockedRequestHandler = $mockedRequestHandler;
100
        $this->requestHandler = $requestHandler;
101
        $this->timeTracker = $timeTracker;
102
        $this->typoScriptFrontendInitialization = $typoScriptFrontendInitialization;
103
    }
104
105
    /**
106
     * Checks if a backend user is logged in.
107
     *
108
     * @return bool
109
     */
110
    public function hasActiveBackendUser()
111
    {
112
        return ($GLOBALS['BE_USER'] ?? null) instanceof BackendUserAuthentication &&
113
            $GLOBALS['BE_USER']->user['uid'] > 0;
114
    }
115
116
    /**
117
     * @return BackendUserAuthentication
118
     * @throws LogicException
119
     */
120
    public function getBackendUser()
121
    {
122
        if ($this->hasActiveBackendUser() === false) {
123
            throw new LogicException('be-user is not initialized - initialize with BE-user with method \'initializeBackendUser\'');
124
        }
125
        return $GLOBALS['BE_USER'];
126
    }
127
128
    /**
129
     * Checks if a frontend user is logged in and the session is active.
130
     *
131
     * @return bool
132
     */
133
    public function hasActiveFrontendUser()
134
    {
135
        $frontendUser = $this->getRequest()->getAttribute('frontend.user');
136
        return ($frontendUser instanceof FrontendUserAuthentication && is_array($frontendUser->user) && isset($frontendUser->user['uid']));
137
    }
138
139
    /**
140
     * @return FrontendUserAuthentication
141
     * @throws LogicException
142
     */
143
    public function getFrontendUser()
144
    {
145
        if ($this->hasActiveFrontendUser() === false) {
146
            throw new LogicException('fe-user is not initialized');
147
        }
148
        return $this->getRequest()->getAttribute('frontend.user');
149
    }
150
151
    /**
152
     * @param integer $pageId
153
     * @param integer $type
154
     *
155
     * @return void
156
     */
157
    public function initializeFrontendRendering($pageId = 0, $type = 0)
158
    {
159
        if ($this->isFrontendInitialized()) {
160
            // FE is already initialized - this can happen when we use/call internal REST-endpoints inside of a normal TYPO3-page
161
            return;
162
        }
163
164
        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
165
        $site = $siteFinder->getSiteByPageId($pageId);
166
        $pageArguments = new PageArguments($pageId, $type, [], [], []);
167
168
        /* @var ServerRequestInterface $request */
169
        $request = $this->getRequest()
170
            ->withAttribute('site', $site)
171
            ->withAttribute('routing', $pageArguments)
172
            ->withAttribute('language', $site->getDefaultLanguage())
173
            ->withQueryParams($_GET)->withCookieParams($_COOKIE);
174
175
        $this->backendUserAuthenticator->process($request, $this->mockedRequestHandler);
176
        $request = $this->mockedRequestHandler->getRequest();
177
178
        $this->frontendUserAuthenticator->process($request, $this->mockedRequestHandler);
179
        $request = $this->mockedRequestHandler->getRequest();
180
181
        $this->typoScriptFrontendInitialization->process($request, $this->mockedRequestHandler);
182
        $request = $this->mockedRequestHandler->getRequest();
183
184
        $prepareTypoScriptFrontendRendering = new PrepareTypoScriptFrontendRendering($GLOBALS['TSFE'], $this->timeTracker);
185
        $prepareTypoScriptFrontendRendering->process($request, $this->mockedRequestHandler);
186
        Loader::setRequest($this->mockedRequestHandler->getRequest());
187
    }
188
189
    /**
190
     * @return string
191
     * @throws LogicException
192
     */
193
    public function renderPageContent()
194
    {
195
        if ($this->isFrontendInitialized() === false) {
196
            throw new LogicException('FrontendRendering is not initialized - initialize with method \'initializeFrontendRendering\'');
197
        }
198
199
        /** @var Response $response */
200
        $response = $this->requestHandler->handle($this->getRequest());
201
        return $response->getBody()->__toString();
202
    }
203
204
    /**
205
     * @param ServerRequestInterface $request
206
     */
207
    public static function setRequest(ServerRequestInterface $request)
208
    {
209
        $GLOBALS['RESTLER_TYPO3_REQUEST'] = $request;
210
    }
211
212
    /**
213
     * @return ServerRequestInterface
214
     */
215
    private function getRequest()
216
    {
217
        return $GLOBALS['RESTLER_TYPO3_REQUEST'];
218
    }
219
220
    /**
221
     * @return boolean
222
     */
223
    private function isFrontendInitialized()
224
    {
225
        return ($GLOBALS['TSFE'] ?? null) instanceof TypoScriptFrontendController &&
226
            $GLOBALS['TSFE']->tmpl instanceof TemplateService;
227
    }
228
}
229