Breaking: #110334 - XML sitemap data provider interface changed
See forge#110334
Description
\TYPO3\ declared a
constructor, which forced every data provider to be instantiated with its
runtime information as constructor arguments. Data providers could therefore
never be resolved by the dependency injection container and had to fetch all
their dependencies statically. In addition, the items of a sitemap had to be
collected in the constructor, since the interface methods took no arguments.
The interface has been changed accordingly:
- The constructor declaration and the methods
get,Key () get,Items () getandLast Modified () gethave been removed in favor of the single methodNumber Of Pages () get.Sitemap () getreceives all runtime information asSitemap () \TYPO3\: The name of the requested sitemap, its configuration, the number of the requested page, the current request and a content object renderer to generate URLs with.CMS\ Seo\ Xml Sitemap\ Xml Sitemap Request getreturns aSitemap () \TYPO3\carrying the items of the requested page, the last modification date and the number of pages of the sitemap.CMS\ Seo\ Xml Sitemap\ Xml Sitemap - Data providers are stateless services now. The interface is tagged with
seo., so implementations are registered in the dependency injection container automatically and are free to use constructor injection.xmlsitemap. provider
Registering a sitemap in TypoScript is unchanged: Data providers are still referenced by their class name.
Impact
Classes implementing
Xml without the method
get will cause a fatal PHP error.
Data providers that are not available as a service in the dependency injection
container are not resolved anymore: Rendering such a sitemap throws a
\TYPO3\, and
the sitemap is skipped in the sitemap index.
Data providers extending
\TYPO3\ keep working
unchanged, see Deprecation: #110334 - AbstractXmlSitemapDataProvider.
Affected installations
All installations with custom extensions implementing
Xml directly. This is a rarely used API,
most data providers extend
Abstract instead.
Migration
Move the collecting of items from the constructor to
get and
take the configuration, the requested page and the content object renderer
from the
Xml. The constructor is free for dependency
injection afterwards:
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemap;
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemapDataProviderInterface;
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemapRequest;
final readonly class MyXmlSitemapDataProvider implements XmlSitemapDataProviderInterface
{
public function __construct(
private MyItemRepository $itemRepository,
) {}
public function getSitemap(XmlSitemapRequest $sitemapRequest): XmlSitemap
{
$items = [];
foreach ($this->itemRepository->findAll($sitemapRequest->configuration) as $item) {
$items[] = [
'uid' => $item['uid'],
'lastMod' => $item['tstamp'],
];
}
return XmlSitemap::forPage(
$items,
$sitemapRequest->page,
fn(array $item): array => $this->defineUrl($item, $sitemapRequest),
);
}
private function defineUrl(array $item, XmlSitemapRequest $sitemapRequest): array
{
$item['loc'] = $sitemapRequest->contentObjectRenderer->createUrl([
'parameter' => $item['uid'],
'forceAbsoluteUrl' => 1,
]);
return $item;
}
}
Xml takes all items of a sitemap, extracts the items of
the requested page and calculates the last modification date and the number of
pages needed by the sitemap index. The optional item mapper is applied to the
items of the requested page only, and only when the items are rendered at all -
the sitemap index does not generate any URL this way. Data providers taking care
of paging themselves, for example by limiting their database query to the items
of the requested page, use
Xml instead:
return XmlSitemap::create(
fn(): array => $this->itemRepository->findForPage($sitemapRequest->page),
$this->itemRepository->findLastModified(),
$this->itemRepository->countPages(),
);
In case the extension supports both TYPO3 v14 and v15, extend
Abstract instead of implementing the interface
directly: Such a data provider is instantiated with its runtime information in
v15 as well, at the cost of a deprecation message. It is then migrated to the
new interface once support for TYPO3 v14 is dropped.