Repository¶
A basic repository can be quite a short class. The shortest possible
repository is an empty class inheriting from
TYPO3\CMS\Extbase\Persistence\Repository
:
<?php
declare(strict_types=1);
namespace TTN\Tea\Domain\Repository\Product;
use TYPO3\CMS\Extbase\Persistence\Repository;
class TeaRepository extends Repository
{
}
The model the repository should deliver is derived from the namespace and
name of the repository. A repository with the fully qualified name
TTN\Tea\Domain\Repository\Product\TeaRepository
therefore delivers
models with the fully qualified name TTN\Tea\Domain\Model\Product\Tea
without further configuration.
In the EXT:tea extension some additional settings are required. These can be done directly in the Repository or in a trait. It is important to know, that a trait overrides parameters and method from the parent class but can be overridden from the current class.
The TeaRepository
configures the $defaultOrderings
directly in
the repository class and imports additional settings from the trait.
<?php
declare(strict_types=1);
namespace TTN\Tea\Domain\Repository\Product;
use TTN\Tea\Domain\Model\Product\Tea;
use TTN\Tea\Domain\Repository\Traits\StoragePageAgnosticTrait;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* @extends Repository<Tea>
*/
class TeaRepository extends Repository
{
use StoragePageAgnosticTrait;
protected $defaultOrderings = ['title' => QueryInterface::ORDER_ASCENDING];
}
We override the protected parameter $defaultOrderings
here. This parameter
is also defined in the parent class
TYPO3\CMS\Extbase\Persistence\Repository
and used here when querying
the database.
The trait itself is also defined in the extension:
<?php
declare(strict_types=1);
namespace TTN\Tea\Domain\Repository\Traits;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
/**
* This trait for repositories makes the repository ignore the storage page setting when fetching models.
*/
trait StoragePageAgnosticTrait
{
public function initializeObject(): void
{
$querySettings = GeneralUtility::makeInstance(Typo3QuerySettings::class);
$querySettings->setRespectStoragePage(false);
$this->setDefaultQuerySettings($querySettings);
}
}
Here we inject the $querySettings
and allow to fetch tea objects from
all pages. We then set these as default query settings.
The advantage of using a trait here instead of defining the parameters and methods directly in the repository is, that the code can be reused without requiring inheritance. Repositories of non-related models should not inherit from each other.
Using the repository¶
The TeaRepository
can now be used in a controller or another class
after it was injected by Dependency Injection:
use TTN\Tea\Domain\Repository\Product\TeaRepository;
class TeaController extends ActionController
{
private TeaRepository $teaRepository;
public function injectTeaRepository(TeaRepository $teaRepository): void
{
$this->teaRepository = $teaRepository;
}
}
Then it can be used:
use Psr\Http\Message\ResponseInterface;
use TTN\Tea\Domain\Repository\Product\TeaRepository;
class TeaController extends ActionController
{
private TeaRepository $teaRepository;
public function indexAction(): ResponseInterface
{
$this->view->assign('teas', $this->teaRepository->findAll());
return $this->htmlResponse();
}
}
The method $this->teaRepository->findAll()
that is called here is
defined in the parent class Repository
.
You can also add additional methods here to query the database. See chapter "Repository" in the Extbase reference. As this example is very basic we do not need custom find methods.