• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TYPO3-Headless / headless / 29398229494

15 Jul 2026 07:42AM UTC coverage: 69.663% (-5.8%) from 75.459%
29398229494

Pull #893

github

web-flow
Merge ab993c965 into 79b7c5472
Pull Request #893: [TASK] Reintroduce missing features, extension cleanup

360 of 545 new or added lines in 33 files covered. (66.06%)

167 existing lines in 7 files now uncovered.

1364 of 1958 relevant lines covered (69.66%)

7.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.69
/Classes/XClass/Controller/LoginController.php
1
<?php
2

3
/*
4
 * This file is part of the "headless" Extension for TYPO3 CMS.
5
 *
6
 * For the full copyright and license information, please read the
7
 * LICENSE.md file that was distributed with this source code.
8
 */
9

10
declare(strict_types=1);
11

12
namespace FriendsOfTYPO3\Headless\XClass\Controller;
13

14
use FriendsOfTYPO3\Headless\Utility\HeadlessModeInterface;
15
use Psr\Http\Message\ResponseInterface;
16
use TYPO3\CMS\Core\Security\RequestToken;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use TYPO3\CMS\FrontendLogin\Event\BeforeRedirectEvent;
19
use TYPO3\CMS\FrontendLogin\Event\LoginErrorOccurredEvent;
20
use TYPO3\CMS\FrontendLogin\Event\LogoutConfirmedEvent;
21
use TYPO3\CMS\FrontendLogin\Event\ModifyLoginFormViewEvent;
22

23
use function implode;
24
use function json_encode;
25

26
class LoginController extends \TYPO3\CMS\FrontendLogin\Controller\LoginController
27
{
28
    private ?HeadlessModeInterface $headlessMode = null;
29

30
    private function getHeadlessMode(): HeadlessModeInterface
31
    {
32
        return $this->headlessMode ??= GeneralUtility::makeInstance(HeadlessModeInterface::class);
2✔
33
    }
34

35
    /**
36
     * Show login form
37
     */
38
    public function loginAction(): ResponseInterface
39
    {
UNCOV
40
        if (!$this->isHeadlessEnabled()) {
×
UNCOV
41
            return parent::loginAction();
×
42
        }
43

UNCOV
44
        $status = 'success';
×
45

UNCOV
46
        if ($this->isLogoutSuccessful()) {
×
UNCOV
47
            $this->eventDispatcher->dispatch(new LogoutConfirmedEvent($this, $this->view, $this->request));
×
UNCOV
48
        } elseif ($this->hasLoginErrorOccurred()) {
×
UNCOV
49
            $status = 'failure';
×
UNCOV
50
            $this->eventDispatcher->dispatch(new LoginErrorOccurredEvent($this->request));
×
51
        }
52

UNCOV
53
        if (($forwardResponse = $this->handleLoginForwards()) !== null) {
×
UNCOV
54
            return $forwardResponse;
×
55
        }
UNCOV
56
        if (($redirectResponse = $this->handleRedirect($status)) !== null) {
×
UNCOV
57
            return $redirectResponse;
×
58
        }
59

UNCOV
60
        $this->eventDispatcher->dispatch(new ModifyLoginFormViewEvent($this->view, $this->request));
×
61

UNCOV
62
        $storagePageIds = ($GLOBALS['TYPO3_CONF_VARS']['FE']['checkFeUserPid'] ?? false)
×
UNCOV
63
            ? $this->pageRepository->getPageIdsRecursive(GeneralUtility::intExplode(',', (string)($this->settings['pages'] ?? ''), true), (int)($this->settings['recursive'] ?? 0))
×
UNCOV
64
            : [];
×
65

UNCOV
66
        $this->view->assignMultiple(
×
UNCOV
67
            [
×
UNCOV
68
                'status' => $status,
×
UNCOV
69
                'storagePid' => implode(',', $storagePageIds),
×
UNCOV
70
                'messageKey' => $this->getStatusMessageKey(),
×
UNCOV
71
                'permaloginStatus' => $this->getPermaloginStatus(),
×
UNCOV
72
                'redirectURL' => $this->redirectHandler->getLoginFormRedirectUrl($this->request, $this->configuration, $this->isRedirectDisabled()),
×
UNCOV
73
                'redirectReferrer' => $this->request->hasArgument('redirectReferrer') ? (string)$this->request->getArgument('redirectReferrer') : '',
×
UNCOV
74
                'referer' => $this->redirectHandler->getReferrerForLoginForm($this->request, $this->settings),
×
UNCOV
75
                'noRedirect' => $this->isRedirectDisabled(),
×
UNCOV
76
                'requestToken' => RequestToken::create('core/user-auth/fe')
×
UNCOV
77
                    ->withMergedParams(['pid' => implode(',', $storagePageIds)]),
×
UNCOV
78
            ]
×
UNCOV
79
        );
×
80

UNCOV
81
        return $this->jsonResponse();
×
82
    }
83

84
    protected function handleRedirect(string $status = 'success'): ?ResponseInterface
85
    {
86
        if ($this->redirectUrl === '') {
3✔
87
            return null;
1✔
88
        }
89

90
        if (!$this->isHeadlessEnabled()) {
2✔
UNCOV
91
            return parent::handleRedirect();
×
92
        }
93

94
        $event = $this->eventDispatcher->dispatch(new BeforeRedirectEvent(
2✔
95
            $this->loginType,
2✔
96
            $this->redirectUrl,
2✔
97
            $this->request
2✔
98
        ));
2✔
99

100
        if ($event->getRedirectUrl() === '') {
2✔
101
            return null;
1✔
102
        }
103

104
        return $this->jsonResponse(json_encode([
1✔
105
            'redirectUrl' => $event->getRedirectUrl(),
1✔
106
            'statusCode' => 303,
1✔
107
            'status' => $status,
1✔
108
        ], JSON_THROW_ON_ERROR));
1✔
109
    }
110

111
    private function isHeadlessEnabled(): bool
112
    {
113
        return $this->getHeadlessMode()->isEnabledFor($this->request);
2✔
114
    }
115
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc