From bcba6bd353161fab456b423e93571ab027d5423c Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 20 Jan 2021 15:59:00 +0100 Subject: New plugin hook: ability to add custom filters to Shaarli search engine A new plugin hook has been added: hook_test_filter_search_entry This hook allows to filter out bookmark with custom plugin code when a search is performed. Related to #143 --- application/plugin/PluginManager.php | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'application/plugin') diff --git a/application/plugin/PluginManager.php b/application/plugin/PluginManager.php index 7fc0cb04..939db1ea 100644 --- a/application/plugin/PluginManager.php +++ b/application/plugin/PluginManager.php @@ -2,6 +2,7 @@ namespace Shaarli\Plugin; +use Shaarli\Bookmark\Bookmark; use Shaarli\Config\ConfigManager; use Shaarli\Plugin\Exception\PluginFileNotFoundException; use Shaarli\Plugin\Exception\PluginInvalidRouteException; @@ -45,6 +46,9 @@ class PluginManager */ protected $errors; + /** @var callable[]|null Preloaded list of hook function for filterSearchEntry() */ + protected $filterSearchEntryHooks = null; + /** * Plugins subdirectory. * @@ -273,6 +277,14 @@ class PluginManager return $this->registeredRoutes; } + /** + * @return array List of registered filter_search_entry hooks + */ + public function getFilterSearchEntryHooks(): ?array + { + return $this->filterSearchEntryHooks; + } + /** * Return the list of encountered errors. * @@ -283,6 +295,50 @@ class PluginManager return $this->errors; } + /** + * Apply additional filter on every search result of BookmarkFilter calling plugins hooks. + * + * @param Bookmark $bookmark To check. + * @param array $context Additional info about search context, depends on the search source. + * + * @return bool True if the result must be kept in search results, false otherwise. + */ + public function filterSearchEntry(Bookmark $bookmark, array $context): bool + { + if ($this->filterSearchEntryHooks === null) { + $this->loadFilterSearchEntryHooks(); + } + + if ($this->filterSearchEntryHooks === []) { + return true; + } + + foreach ($this->filterSearchEntryHooks as $filterSearchEntryHook) { + if ($filterSearchEntryHook($bookmark, $context) === false) { + return false; + } + } + + return true; + } + + /** + * filterSearchEntry() method will be called for every search result, + * so for performances we preload existing functions to invoke them directly. + */ + protected function loadFilterSearchEntryHooks(): void + { + $this->filterSearchEntryHooks = []; + + foreach ($this->loadedPlugins as $plugin) { + $hookFunction = $this->buildHookName('filter_search_entry', $plugin); + + if (function_exists($hookFunction)) { + $this->filterSearchEntryHooks[] = $hookFunction; + } + } + } + /** * Checks whether provided input is valid to register a new route. * It must contain keys `method`, `route`, `callable` (all strings). -- cgit v1.2.3