Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Ahondev/portfolio-v2/llms.txt

Use this file to discover all available pages before exploring further.

Service providers are the canonical extension point for the WP SSR Framework. Each provider has two responsibilities: register() binds things into the services container before any hooks run, and boot() adds WordPress action/filter hooks and starts services. Providers are collected by the Kernel, sorted by their $priority integer, and executed in order — giving you total control over the sequence in which features initialise.

ServiceProviderInterface

Every provider must implement this two-method contract.
namespace Ahon\WPCMS\Providers;

interface ServiceProviderInterface
{
    public function register(): void;
    public function boot(): void;
}
register()
void
Called synchronously during Kernel::boot(), before any WordPress hooks fire. Use it to perform lightweight setup that other providers may depend on at register() time — for example, adding an entry to the services container.
boot()
void
Deferred to the WordPress init hook at the provider’s $priority. This is where you call add_action(), add_filter(), or start services that depend on WordPress being initialised.

BaseServiceProvider

Extend this class to create your own providers. It implements ServiceProviderInterface with empty default methods so you only need to override what you use.
namespace Ahon\WPCMS\Providers;

class BaseServiceProvider extends Base implements ServiceProviderInterface
{
    public static int $priority = 0;

    public function register(): void {}
    public function boot(): void {}
}

$priority

$priority
int
Controls when boot() is called relative to other providers. Lower numbers run first. The ProviderManager passes this value as the priority argument to add_action('init', ...). Defaults to 0.

Inherited from Base

BaseServiceProvider extends Base, giving every provider access to two helper methods:

service()

Resolves a class from the ServicesContainer. The instance is lazy-created on first access and cached for the lifetime of the request.
protected function service(string $class): mixed
// Inside a provider's boot() method
$mailer = $this->service(MailerService::class);
$mailer->send($to, $subject, $body);

remember()

A transient-backed cache helper. On the first call the callback is executed and its return value is stored as a WordPress transient; subsequent calls within the TTL window return the cached value.
protected function remember(string $key, int $ttl, callable $callback): mixed
key
string
required
Unique transient key.
ttl
int
required
Time-to-live in seconds.
callback
callable
required
The computation to cache. Executed only when no valid transient exists.

ServicesContainer

A minimal service locator that lazy-instantiates and caches service instances by class name.
namespace Ahon\WPCMS\Service;

class ServicesContainer
{
    public static function resolve(string $class): mixed;
}

resolve()

Returns the singleton instance of $class, constructing it on first call. Throws Exception if the class does not exist.
ServicesContainer::resolve(ContactService::class);
ServicesContainer constructs each class with new $class — no dependency injection. Design your services to be constructable without arguments, and pull dependencies via $this->service() inside method bodies if needed.

ProviderManager

The internal engine that registers and boots providers. Called once by Kernel::boot().
class ProviderManager
{
    public static function registerProviders(array $providers): void;
}

Registration flow

1

Validate

Checks that the class exists and extends BaseServiceProvider. Throws RuntimeException on failure.
2

Instantiate

Creates a new instance of the provider.
3

Register

Calls $provider->register() synchronously.
4

Schedule boot

Calls add_action('init', fn() => $provider->boot(), $provider::$priority). The boot callback fires during WordPress init at the provider’s configured priority.

Built-in Providers

The following providers ship with the framework and are registered in wp-ssr.php. They run in the order listed, subject to their individual $priority values.

Creating a Custom Provider

1

Create the class

Create a new file in app/Providers/ extending BaseServiceProvider.
<?php

namespace Ahon\WPCMS\App\Providers;

use Ahon\WPCMS\Providers\BaseServiceProvider;
use Ahon\WPCMS\App\Services\MailerService;

class MailServiceProvider extends BaseServiceProvider
{
    // Boot after core providers
    public static int $priority = 20;

    public function register(): void
    {
        // Nothing to bind before WordPress is ready
    }

    public function boot(): void
    {
        // Hook into WordPress after `init`
        add_action('wp_mail_failed', function (\WP_Error $error) {
            $mailer = $this->service(MailerService::class);
            $mailer->logFailure($error->get_error_message());
        });

        // Use the remember helper for expensive lookups
        $config = $this->remember('mail_config', 3600, function () {
            return get_option('mail_config_options', []);
        });
    }
}
2

Register in Kernel

Add the class to the withProviders() array in wp-ssr.php.
Kernel::configure()
    ->withProviders([
        Ahon\WPCMS\App\Providers\AppServiceProvider::class,
        Ahon\WPCMS\App\Providers\RateLimitServiceProvider::class,
        Ahon\WPCMS\App\Providers\CacheServiceProvider::class,
        Ahon\WPCMS\App\Providers\AnalyticsServiceProvider::class,
        Ahon\WPCMS\App\Providers\SEOServiceProvider::class,
        Ahon\WPCMS\App\Providers\RoutingServiceProvider::class,
        Ahon\WPCMS\App\Providers\SSGServiceProvider::class,
        // ↓ your new provider
        Ahon\WPCMS\App\Providers\MailServiceProvider::class,
    ])
    ->boot();
Set $priority carefully. A provider with $priority = 0 boots before SEOServiceProvider ($priority = 40), so it cannot iterate PostType::all() reliably — post types are not yet registered that early. Use a priority above 20 if your provider depends on post types.

Priority Reference

PriorityProvider
0 (default)AppServiceProvider, RateLimitServiceProvider, CacheServiceProvider, AnalyticsServiceProvider, RoutingServiceProvider, SSGServiceProvider
40SEOServiceProvider
Provider boot priority maps directly to the WordPress init hook priority. Standard WordPress themes and plugins hook at priority 10 by default. Providers with $priority = 0 run before them; $priority = 40 runs after.

Build docs developers (and LLMs) love