It is essential to be able to associate custom repository implementations to your entities. You are able to create any repository from scratch, especially for non SQL sources. However, the most common use case would be extending the default repository implementation to add custom selectors.
To create a custom repository associated with a SQL data source simply extend the primary
class Cycle\ORM\Select\Repository
:
namespace Example\Repository;
class UserRepository extends \Cycle\ORM\Select\Repository
{
// ...
}
Use the Entity
attribute to create the association:
namespace Example;
use Cycle\Annotated\Annotation as Cycle;
#[Cycle\Entity(repository: Example\Repository\UserRepository::class)]
class User
{
// ...
}
Note
This applies to theannotated
extension only. Other schema declaration approaches will differ in implementation.
Update/calculate your schema to get access to the newly assigned repository through the getRepository
method of the
orm:
$repository = $orm->getRepository(\Example\User::class);
print_r($repository::class);
Note
You can assign a single repository implementation to multiple entities.
The main reason for using custom repositories is the ability to write your own find
methods. You can do that using
base select
method which returns you the instance of Cycle\ORM\Select
:
namespace Example\Repository;
use Cycle\ORM\Select;
class UserRepository extends Select\Repository
{
public function findActive(): Select
{
return $this->select()->where('status', 'active');
}
}
Note
You can also chain your select methods$this->findActive()->where('age', '>', $age);
as long as you return theSelect
object from your method.
Now you can access this method:
print_r($orm->getRepository(\Example\User::class)->findActive()->fetchAll());
Warning
Don't mutate theRepository::$select
object. Always useRepository::select()
method to get a Select object clone. You can mutate the$select
property only in a repository clone (see Chained Repository).
Another use-case is to automatically preload some entity relations using a custom find method:
use Cycle\ORM\Select;
class UserRepository extends Select\Repository
{
// ...
public function findActiveUsersLoadAddress(): Select
{
return $this->findActive()->load('address');
}
}