Repository
A basic repository can be quite a short class. The shortest possible
repository is an empty class inheriting from
\TYPO3\
:
<?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\
therefore delivers
models with the fully qualified name \TTN\
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 Tea
configures the $default
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\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
/**
* @extends Repository<Tea>
*/
class TeaRepository extends Repository
{
use StoragePageAgnosticTrait;
protected $defaultOrderings = ['title' => QueryInterface::ORDER_ASCENDING];
/**
* @param positive-int $ownerUid
*/
public function findByOwnerUid(int $ownerUid): QueryResultInterface
{
$query = $this->createQuery();
$query->matching($query->equals('ownerUid', $ownerUid));
return $query->execute();
}
}
We override the protected parameter $default
here. This parameter
is also defined in the parent class
\TYPO3\
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 $query
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 \TTN\
can now be used in a
controller or another class.
Require it via Dependency Injection:
use TTN\Tea\Domain\Repository\Product\TeaRepository;
class TeaController extends ActionController
{
private TeaRepository $teaRepository;
public function __construct(TeaRepository $teaRepository)
{
$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->tea
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.