Reading records stored in another site
Two things have to be settled before a query can return records from another site: which pages to read, and which language to ask for. This page covers the pages. The language has its own page.
Naming the storage pages
The storage pages of another site are ordinary page UIDs, and the storagePid configuration accepts them. Nothing checks that they belong to the current site.
For a setup with matching language configuration this is all it takes: configure the shared folder as the storagePid in TypoScript, or let an editor choose it in the Behavior > Starting point field of the plugin, and every query the repository builds reads from there.
Hint
Hard-coding a page UID in TypoScript ties the extension to one
installation, so prefer a site setting or a
plugin FlexForm field that names the page, and read the value from
$this->settings
in the controller.
Overriding the storage pages for one query
Where the storage pages are decided at runtime — different for each visitor, each plugin instance or each site — the query settings carry the decision instead:
<?php
namespace MyVendor\MyExtension\Domain\Repository;
use MyVendor\MyExtension\Domain\Model\Conference;
use TYPO3\CMS\Core\Context\LanguageAspect;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
class ConferenceRepository extends Repository
{
/**
* Reads conferences from storage pages that need not belong to the current
* site, in the language the caller resolved for those pages.
*
* @param int[] $storagePageIds
* @return QueryResultInterface<Conference>
*/
public function findAllInStorage(
array $storagePageIds,
LanguageAspect $languageAspect,
): QueryResultInterface {
$query = $this->createQuery();
$querySettings = $query->getQuerySettings();
$querySettings->setStoragePageIds($storagePageIds);
$querySettings->setLanguageAspect($languageAspect);
return $query->execute();
}
}
set replaces the configured storagePid for this one
query. The repository takes both the pages and the language aspect as
arguments, so it makes no assumption about which site either came from. That
keeps it usable from a plugin, a backend module and a command alike.
Note
set also makes records from other sites
reachable, by dropping the page restriction altogether. It is a blunt
instrument for this purpose: the query then searches the whole table,
including records from sites you never intended to expose, and including
records an editor has filed somewhere unrelated. Name the pages you want
rather than removing the restriction.
Finding the storage site
Reading the language configuration of the storage site — which the
next page needs — means resolving the
Site
object it belongs to.
\TYPO3\ offers three ways in, and the choice
matters:
| Method | Use it when |
|---|---|
get | The storage site is known by name from configuration. This is the most robust option: the identifier is stable, readable in a site setting, and survives page UIDs changing. |
get | Only the storage page UID is known. Resolves the site from the page it sits in. |
get | The root page UID of the storage site is known. |
See also
Finding a site object with the SiteFinder class
— full documentation of
Site.
What this means for relations
Relation queries ignore the storagePid entirely: Extbase sets
set on them. Relations therefore reach records
the parent query could never have returned, wherever in the page tree they are
stored.
For cross-site reading this works in your favor — a conference in the shared folder keeps its categories regardless of which site reads it, and you need do nothing to make that happen. The same mechanism also means a relation can pull in a record from a storage folder you did not intend to expose, which is worth knowing when the related table holds site-specific data.
The language of relations is a separate question, covered on the next page.