Hi there,
i have recently discovered the service feature (PKPServicesContainer
) and I want to provide services from plugins.
The services available via ServicesContainer::instance()->get()
are hardcoded in the provider registered for the specific product e.g. OJSServiceProvider
. Now i need a solution to register the services somehow without touching the core files.
Here is my current solution:
-
Add a hook in
PKPServicesContainer::get()
public function get($service) { HookRegistry::call('PKPServicesContainer::beforeGet', array($this, $this->container, $service)); return $this->container[$service]; }
-
Listen to the hook call in a plugin …
public function register($category, $path, $mainContextId = null) { HookRegistry::register('PKPServicesContainer::beforeGet', array($this, 'pkpServicesContainerBeforeGet')); }
-
… to register the service when the hook call is executed
public function pkpServicesContainerBeforeGet($hookName, $args) { $container = $args[1]; $service = $args[2]; if ($service == 'submissionWizardRequest' && !isset($container['submissionWizardRequest'])) $container->register(new SubmissionWizardRequestServiceProvider()); }
Before anyone asks why i did not add a hook to PKPServicesContainer::init()
- i would need to add the hook to every product that uses pkp-lib (OJS, OMP, …)
- the
PKPServicesContainer::init()
call might be executed to early e.g. when a plugin tries to request a service on registration stage, meaning that plugins coming later in the registration chain cannot hook toPKPServicesContainer::init()
becausePKPServicesContainer::init()
is called only once due toPKPServicesContainer
being a singleton
The solution should not break anything as it is an optional hook. Perhaps another developer wants to use services too, so may I provide a PR to integrate this feature into pkp-lib
?
So lonG
Daniel