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

eliashaeussler / typo3-warming / 15615316958

12 Jun 2025 03:52PM UTC coverage: 91.686% (+0.4%) from 91.289%
15615316958

push

github

eliashaeussler
[TASK] Remove outdated `@throws` annotations

1610 of 1756 relevant lines covered (91.69%)

12.0 hits per line

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

98.97
/Classes/EventListener/UrlMetadataListener.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "warming".
7
 *
8
 * Copyright (C) 2021-2025 Elias Häußler <elias@haeussler.dev>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace EliasHaeussler\Typo3Warming\EventListener;
25

26
use EliasHaeussler\CacheWarmup;
27
use EliasHaeussler\Typo3Warming\Http;
28
use GuzzleHttp\Exception;
29
use Psr\Http\Message;
30
use TYPO3\CMS\Backend;
31
use TYPO3\CMS\Core;
32

33
/**
34
 * UrlMetadataListener
35
 *
36
 * @author Elias Häußler <elias@haeussler.dev>
37
 * @license GPL-2.0-or-later
38
 */
39
final readonly class UrlMetadataListener
40
{
41
    public function __construct(
27✔
42
        private Backend\Module\ModuleProvider $moduleProvider,
43
        private Backend\Routing\UriBuilder $uriBuilder,
44
        private Http\Message\UrlMetadataFactory $urlMetadataFactory,
45
    ) {}
27✔
46

47
    // @todo Enable attribute once support for TYPO3 v12 is dropped
48
    // #[\TYPO3\CMS\Core\Attribute\AsEventListener('eliashaeussler/typo3-warming/url-metadata/on-success')]
49
    public function onSuccess(CacheWarmup\Event\Crawler\UrlCrawlingSucceeded $event): void
8✔
50
    {
51
        $metadata = $this->urlMetadataFactory->createFromResponse($event->response());
8✔
52

53
        if ($metadata !== null) {
8✔
54
            $result = CacheWarmup\Result\CrawlingResult::createSuccessful(
7✔
55
                $event->result()->getUri(),
7✔
56
                $this->extendResultData($event->result(), $metadata),
7✔
57
            );
7✔
58

59
            $event->setResult($result);
7✔
60
        }
61
    }
62

63
    // @todo Enable attribute once support for TYPO3 v12 is dropped
64
    // #[\TYPO3\CMS\Core\Attribute\AsEventListener('eliashaeussler/typo3-warming/url-metadata/on-failure')]
65
    public function onFailure(CacheWarmup\Event\Crawler\UrlCrawlingFailed $event): void
19✔
66
    {
67
        $metadata = null;
19✔
68
        $exception = $event->exception();
19✔
69

70
        if ($exception instanceof Exception\RequestException && ($response = $exception->getResponse()) !== null) {
19✔
71
            $metadata = $this->urlMetadataFactory->createFromResponse($response);
17✔
72
        }
73

74
        if ($metadata !== null) {
19✔
75
            $result = CacheWarmup\Result\CrawlingResult::createFailed(
16✔
76
                $event->result()->getUri(),
16✔
77
                $this->extendResultData($event->result(), $metadata),
16✔
78
            );
16✔
79

80
            $event->setResult($result);
16✔
81
        }
82
    }
83

84
    /**
85
     * @return array<string, mixed>
86
     */
87
    private function extendResultData(
23✔
88
        CacheWarmup\Result\CrawlingResult $result,
89
        Http\Message\UrlMetadata $metadata,
90
    ): array {
91
        $data = $result->getData();
23✔
92
        $data['urlMetadata'] = $metadata;
23✔
93
        $data['pageActions'] = $this->buildPageActions($metadata);
23✔
94

95
        return $data;
23✔
96
    }
97

98
    /**
99
     * @return array{
100
     *     editRecord?: string,
101
     *     viewLog?: string,
102
     * }
103
     */
104
    private function buildPageActions(Http\Message\UrlMetadata $metadata): array
23✔
105
    {
106
        // Early return if page id is missing
107
        if ($metadata->pageId === null) {
23✔
108
            return [];
2✔
109
        }
110

111
        // Early return if we're not in backend context
112
        if (!$this->isRunningInBackendContext()) {
21✔
113
            return [];
4✔
114
        }
115

116
        $backendUser = $this->getBackendUser();
17✔
117

118
        // Early return if backend user is not available (should never happen, but who knows)
119
        if ($backendUser === null) {
17✔
120
            return [];
2✔
121
        }
122

123
        $pageTranslationId = $metadata->pageId;
15✔
124
        $actions = [];
15✔
125

126
        // Fetch page translation
127
        if ($metadata->languageId > 0) {
15✔
128
            $pageTranslations = Backend\Utility\BackendUtility::getRecordLocalization(
11✔
129
                'pages',
11✔
130
                $metadata->pageId,
11✔
131
                $metadata->languageId,
11✔
132
            );
11✔
133

134
            if ($pageTranslations !== false && $pageTranslations !== []) {
11✔
135
                $pageTranslationId = (int)$pageTranslations[0]['uid'];
11✔
136
            }
137
        }
138

139
        // Add uri to edit current page record
140
        if ($this->moduleProvider->accessGranted('web_layout', $backendUser)) {
15✔
141
            $actions['editRecord'] = (string)$this->uriBuilder->buildUriFromRoute(
12✔
142
                'record_edit',
12✔
143
                [
12✔
144
                    'edit' => [
12✔
145
                        'pages' => [
12✔
146
                            $pageTranslationId => 'edit',
12✔
147
                        ],
12✔
148
                    ],
12✔
149
                    'returnUrl' => (string)$this->uriBuilder->buildUriFromRoute(
12✔
150
                        'web_layout',
12✔
151
                        [
12✔
152
                            'id' => $metadata->pageId,
12✔
153
                        ],
12✔
154
                    ),
12✔
155
                    'overrideVals' => [
12✔
156
                        'pages' => [
12✔
157
                            'sys_language_uid' => $metadata->languageId ?? 0,
12✔
158
                        ],
12✔
159
                    ],
12✔
160
                ],
12✔
161
                Backend\Routing\UriBuilder::SHAREABLE_URL,
12✔
162
            );
12✔
163
        }
164

165
        if ((new Core\Information\Typo3Version())->getMajorVersion() >= 13) {
15✔
166
            $systemLogModuleIdentifier = 'system_log';
15✔
167
        } else {
168
            // @todo Remove once support for TYPO3 v12 is dropped
169
            $systemLogModuleIdentifier = 'system_BelogLog';
×
170
        }
171

172
        // Add uri to view logs for current page
173
        if (Core\Utility\ExtensionManagementUtility::isLoaded('belog') &&
15✔
174
            $this->moduleProvider->accessGranted($systemLogModuleIdentifier, $backendUser)
15✔
175
        ) {
176
            $actions['viewLog'] = (string)$this->uriBuilder->buildUriFromRoute(
11✔
177
                $systemLogModuleIdentifier . '.BackendLog_list',
11✔
178
                [
11✔
179
                    'constraint' => [
11✔
180
                        'pageId' => $pageTranslationId,
11✔
181
                    ],
11✔
182
                ],
11✔
183
                Backend\Routing\UriBuilder::SHAREABLE_URL,
11✔
184
            );
11✔
185
        }
186

187
        return $actions;
15✔
188
    }
189

190
    private function isRunningInBackendContext(): bool
21✔
191
    {
192
        $serverRequest = $this->getServerRequest();
21✔
193

194
        if ($serverRequest === null) {
21✔
195
            return false;
2✔
196
        }
197

198
        return Core\Http\ApplicationType::fromRequest($serverRequest)->isBackend();
19✔
199
    }
200

201
    private function getBackendUser(): ?Core\Authentication\BackendUserAuthentication
17✔
202
    {
203
        $backendUser = $GLOBALS['BE_USER'] ?? null;
17✔
204

205
        if ($backendUser instanceof Core\Authentication\BackendUserAuthentication) {
17✔
206
            return $backendUser;
15✔
207
        }
208

209
        return null;
2✔
210
    }
211

212
    private function getServerRequest(): ?Message\ServerRequestInterface
21✔
213
    {
214
        $serverRequest = $GLOBALS['TYPO3_REQUEST'] ?? null;
21✔
215

216
        if ($serverRequest instanceof Message\ServerRequestInterface) {
21✔
217
            return $serverRequest;
19✔
218
        }
219

220
        return null;
2✔
221
    }
222
}
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