Bug 19306 - Adding hooks to the plugin system
Summary: Adding hooks to the plugin system
Status: NEW
Alias: None
Product: Koha
Classification: Unclassified
Component: Architecture, internals, and plumbing (show other bugs)
Version: unspecified
Hardware: All All
: P5 - low enhancement (vote)
Assignee: Bugs List
QA Contact: Testopia
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-13 09:38 UTC by Stefan Berndtsson
Modified: 2020-11-20 14:30 UTC (History)
9 users (show)

See Also:
Change sponsored?: ---
Patch complexity: ---
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:


Attachments
Bug in run_matching when plugins are not available (1.14 KB, text/plain)
2017-09-13 09:41 UTC, Stefan Berndtsson
Details
Adding hooks to the plugin system (3.23 KB, patch)
2017-09-13 09:45 UTC, Stefan Berndtsson
Details | Diff | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Berndtsson 2017-09-13 09:38:50 UTC
We've been working on adding hook functionality to the existing plugin system.

This is very much proof-of-concept code at the moment, but here is how it works.

1. Somewhere in the code you add a hook-call with a name for that hook, and pass in some data relevant to that hook.
2. Each plugin with a method matching the hook name is called in sequence, with the data as input and returning data of similar form, which is then passed on to the next matching plugin.
3. The end result is returned back from the hook-call, is put back in place, and code execution is resumed.

The PoC code adds a Koha::Plugins::Handler->run_matching() method that looks up the relevant loaded plugins (using GetPlugins) and calls Koha::Plugins::Handler->run() on each of them.

If plugins are not enabled, or if there is no plugin matching the hook, the input data is returned back, resulting in unaffected operation.

One hook is added in Koha::SearchEngine::Elasticsearch::QueryBuilder.pm, in build_query_compat with the name "build_query_before", which is simply run before the query parsing takes place.

A very simple example plugin is available at:
https://github.com/ub-digit/koha-plugin-build-query-example/releases

This plugin edits a query beginning with "Provider:" to do "publisher:" instead. A simple example that when using Elasticsearch makes publisher links in the bibliographic detail view clickable. The current XSLT uses the Zebra based links, that result in an unusable search. This is not meant to be the solution to the Zebra/Elasticsearch conflict in the XSLT, but it's a simple demonstration of the hook feature.
Comment 1 Stefan Berndtsson 2017-09-13 09:41:14 UTC
Created attachment 67108 [details]
Bug in run_matching when plugins are not available
Comment 2 Stefan Berndtsson 2017-09-13 09:45:42 UTC
Created attachment 67109 [details] [review]
Adding hooks to the plugin system
Comment 3 Katrin Fischer 2017-10-08 14:00:04 UTC
>This plugin edits a query beginning with "Provider:" to do "publisher:" instead. A simple example that when using Elasticsearch makes publisher links in the bibliographic detail view clickable. The current XSLT uses the Zebra based links, that result in an unusable search. This is not meant to be the solution to the Zebra/Elasticsearch conflict in the XSLT, but it's a simple demonstration of the hook feature.

Maybe this should be filed as a separate bug?
Comment 4 Kyle M Hall 2018-10-15 12:35:35 UTC
This adds a very nice convenience method. I'd love to see a followup to replace the existing bespoke looks for opac hooks, staff hooks, and payment plugins if we are to add this.
Comment 5 Stefan Berndtsson 2018-10-22 11:11:52 UTC
The way I see this there are three kinds of "plugins". This idea adds a fourth.

1. Report-plugin.
2. Tool-plugin.
3. "Normal" plugin.
4. "Hooks".

The normal plugin is meant to run once, in a very particular circumstance where the result of the plugin isn't necessarily meant to be passed on to any other plugin. An example here is the to_marc feature used when importing records. Input can be CSV and output is MARC.

A hook on the other hand is meant to return data in the same format as it was received, so that they are chainable. Multiple plugins can be available for the same hook. An example for this case could be modifying MARC-data on its way to the database (for those familiar with Rails, this would be similar to a before_save hook), or adding extra fields into the index without changing the data, in a before_index hook.

We currently use the latter in our Koha instance where we want to be able to distinguish books from ebooks for example, where the qualification for these come from multiple MARC fields. The plugin used for this looks at the MARC-record, combines everything and adds a 998$a with the result which is then indexed and searchable. Many such plugins could be chained in sequence for different kinds of index-preparations.

It may therefor not be sensible to replace things all throughout the code, and that 3 and 4 may need to live beside each other.
Comment 6 Fridolin Somers 2020-11-20 14:30:07 UTC
Is this implemented by Koha::Plugins->call() ?