To bind a custom repository to Statamic's service provider, you need to understand the role of repositories in Statamic and how they interact with its service container. Statamic uses a repository pattern to decouple data retrieval and manipulation from the underlying storage implementation. By default, repositories pull data from Statamic's "Stache," a file-backed caching system. However, for advanced use cases, such as when data is stored in a traditional database or a remote API, you may want to create and bind a custom repository implementation.
Understanding Statamic Repositories
Each type of content in Statamic, like entries, taxonomies, or globals, is typically accessed through a repository interface. The repository acts as a contract that defines methods for fetching, querying, and persisting data.
For example, when fetching entries from a collection named "blog" using:
php
Entry::whereCollection('blog')
Statamic internally delegates the call to an entry repository contract, which determines how and where data is retrieved.
The core Statamic implementation binds contracts to repositories that access the Stache by default. Custom repositories enable you to change this logic by binding a different class to the repository contract.
Creating a Custom Repository
To build a custom repository:
1. Implement the Repository Interface: Your class should implement the corresponding Statamic repository contract. For entries, this would be `Statamic\Contracts\Entries\EntryRepository`. You can extend the default repository class (such as `Statamic\Stache\Repositories\EntryRepository`) to inherit existing behavior for partial customization.
2. Implement Required Methods: A repository typically exposes methods to query, create, update, and delete content. Your class needs to fulfill these contracts adequately.
3. Custom Data Classes: Each repository also creates instances of data classes, such as `Entry`. You can override the `bindings` method on your repository class to specify your custom data model classes.
php
public static function bindings(): array
{
return [
\Statamic\Contracts\Entries\Entry::class => \App\CustomEntry::class,
\Statamic\Contracts\Entries\QueryBuilder::class => \App\CustomEntryQueryBuilder::class,
];
}
Binding Your Repository in a Service Provider
Once your repository class is ready, you bind it to the Statamic repository contract inside your Statamic service provider. This is typically done in the `register` method of your service provider class.
Here's how you can do it:
php
app->bind(
\Statamic\Contracts\Entries\Entry::class,
\App\CustomEntry::class
);
}
It is important to clear the cache after rebinding classes to avoid old bindings being cached by Laravel.
Example: A Database-Backed Entry Repository Implementation
Imagine you want to implement an entry repository that stores entries in a MySQL database rather than files. Your repository might extend the default `EntryRepository` class but override necessary methods to interact with the database using Laravel's Eloquent ORM.
You would:
- Define an Eloquent `Entry` model representing the database table structure.
- Override retrieval methods to query the database instead of the Stache.
- Override saving methods to persist entry data into database columns, possibly handling JSON data for flexible fields.
- Handle common fields like `id`, `site`, `collection`, `slug`, `status`, and `data` as a JSON column.
In your database migration, you might define a table schema:
php
Schema::create('entries', function (Blueprint $table) {
$table->string('id');
$table->string('site');
$table->string('origin_id')->nullable();
$table->boolean('published')->default(true);
$table->string('status');
$table->string('slug');
$table->string('uri')->nullable();
$table->string('date')->nullable();
$table->string('collection');
$table->json('data');
$table->timestamps();
});
Your repository would load, save, and query records from this table while preserving Statamic's contract expectations.
Service Provider Setup
Your service provider is essential in telling Statamic to use your new implementation. It must extend from `Illuminate\Support\ServiceProvider` or, when creating an add-on, extend `Statamic\Providers\AddonServiceProvider`.
Your provider class would look like:
```php
sitory()` in your service provider's `register()` method.
4. Optionally, bind custom data model classes in the `boot()` method.
5. Register your service provider with Laravel and ensure caches are cleared.
This approach offers powerful extensibility, enabling Statamic sites to serve content from virtually any data store, not just files, while preserving the familiar Statamic API and content modeling conventions. The repository pattern and Laravel's service container binding make this integration seamless and maintainable.
These mechanisms together allow for sophisticated, scalable custom data storage solutions while integrating tightly with Statamic's core architecture.
References: Statamic official docs for repositories and service providers.