Architecture
Service Provider
Service providers act as the key method of extending the framework and bootstrapping essential services. Core application functionality will be defined and encapsulated entirely in a service provider. Your own application, as well as all core Mantle services, are bootstrapped via Service Providers.
But, what do we mean by "bootstrapped"? In general, we mean registering things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application.
What would be a service provider?
A good example of what should be a service provider would be a feature in your application. For example, a network of sites have a feature to syndicated content between sites. The feature could be wrapped into a single service provider which would bootstrap and setup all required services. The service provider would be the starting point for that feature.
Registering a Service Provider
The application stores service providers in the config/app.php
file includes
with Mantle. There is a providers
array of classes in that file that include
all providers the application will initialize on each request.
// Inside of config/app.php...
'providers' => [
// Add provider here...
App\Providers\App_Service_Provider::class,
],
Writing a Service Provider
Service providers extend the Mantle\Support\Service_Provider
class and
include a register
and boot
method. The register
method is used to
register application services with the application container. The boot
method
is used to boot provider, setup any classes, register any WordPress hooks, etc.
The boot
method should always call the parent boot method via parent::boot();
.
A service provider can be generated for you by running the following command:
wp mantle make:provider <name>
Service Provider Structure
namespace App;
use Mantle\Support\Service_Provider;
/**
* Example_Provider Service Provider
*/
class Example_Provider extends Service_Provider {
/**
* Register the service provider.
*/
public function register() {
// Register the provider.
$this->app->singleton(
'binding-to-register',
function( $app ) {
return new Essential_Service( $app );
}
);
}
/**
* Boot the service provider.
*/
public function boot() {
parent::boot();
// Boot the provider.
}
}
Automatic Registration with WordPress Events
Service providers are the heart of your application. They can register services and add event listeners that are fired when specific events/actions happen in WordPress. Mantle supports automatic registration of event listeners using PHP attributes:
use Mantle\Support\Attributes\Action;
class Example_Provider extends Service_Provider {
#[Action('wp_loaded')]
public function handle_loaded_event() {
// Called on wp_loaded at priority 10.
}
#[Action('admin_screen', 20)]
public function handle_admin_screen_event() {
// Called on admin_screen at priority 20.
}
}
The service provider also supports magic methods that automatically register
provider methods with WordPress actions and filters. The service provider will
automatically register hooks for the provider by checking for methods that use
the format of on_{hook}
and on_{action}_at_{priority}
as method names. Both
actions and filters are supported using the same method naming convention.
class Example_Provider extends Service_Provider {
public function on_wp_loaded() {
// Called on wp_loaded at priority 10.
}
public function on_admin_screen_at_99() {
// Called on admin_screen at priority 99.
}
}
Service Container
The service container is a powerful tool for managing class dependencies and performing dependency injection with ease. Most function calls are performed through the service container and support dynamic dependency injection without any need to configure it.
Here is an example of the global instance of Shared_Object
being injected into
the controller's constructor. The instance is a global singleton the service
container dynamically included as a parameter to the controller's constructor.
namespace App\Http\Controllers;
use App\Shared_Object;
class Example_Controller extends \Mantle\Http\Controller {
public function __construct( Shared_Object $object ) {
$this->object = $object;
}
public function method( $id ) {
return $this->object->get( $id );
}
}
For more information about the service container and the underlying concept of Dependency Injection, read this document on Understanding Dependency Injection.
Facades
Facades are a static interface to the instances available from the service container. Instead of determining the underlying class or resolving it through the application, a facade will provide a single-line interface to call a singleton object from the container.
use Mantle\Facade\Config;
echo Config::get( 'app.attribute' );
In this example, the config facade is a wrapper for the config
singleton instance of Mantle\Config\Repository
in the application's service container.
Aliases
Aliases provide a root namespace level way of interfacing with classes in the framework. When combined with facades, they can provide a simple way of interfacing with singleton objects deep in the framework.
Log::info( 'My log message!' );
// Can be rewritten as...
app()['log']->info( 'My log message!' );