Page context menu: Purge from SSR cache

SsrPurgeItemProvider adds the item behind Clear cache for real pages (doktype < 199) whenever the purge endpoint is configured. The callback module posts the page uid to the new vitec_ssr_purge_page ajax route, which resolves the page path through the site router, purges it via SsrPurgeService (trigger contextmenu:username, logged as usual) and reports back as a toast notification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
orascheandClaude Fable 5 committed 2026-11-09 21:10:30 +01:00
1 parent fa63871da7
commit 5b524bfce9
4 files changed
+132

No files matched your search

@@ -12,9 +12,11 @@ use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Http\RedirectResponse;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -100,6 +102,32 @@ final class SsrController
return new RedirectResponse((string)$this->uriBuilder->buildUriFromRoute('web_vitecssr'), 303);
}
/**
* Ajax route vitec_ssr_purge_page: purge exactly one page, called by
* the page tree context menu item (ssr-context-menu.js).
*/
public function purgePage(ServerRequestInterface $request): ResponseInterface
{
$body = (array)($request->getParsedBody() ?? []);
$pageUid = (int)($body['pageUid'] ?? ($request->getQueryParams()['pageUid'] ?? 0));
if ($pageUid <= 0) {
return new JsonResponse(['success' => false, 'message' => 'No page uid given'], 400);
}
try {
$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageUid);
$path = $site->getRouter()->generateUri($pageUid)->getPath() ?: '/';
} catch (\Throwable) {
return new JsonResponse(['success' => false, 'message' => 'Page has no routable URL (folder?)']);
}
$user = (string)($GLOBALS['BE_USER']->user['username'] ?? '?');
$result = $this->purgeService->purge([$path], 'contextmenu:' . $user);
return new JsonResponse([
'success' => $result['success'],
'path' => $path,
'message' => 'HTTP ' . $result['httpCode'] . ' - ' . $result['message'],
]);
}
private function rows(string $table, int $limit): array
{
try {