package Koha::SuggestionEngine; # Copyright 2012 C & P Bibliography Services # # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # Koha is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Koha; if not, see . =head1 NAME Koha::SuggestionEngine - Dispatcher class for suggestion engines =head1 SYNOPSIS use Koha::SuggestionEngine; my $suggestor = Koha::SuggestionEngine->new(%params); $suggestor->get_suggestions($search) =head1 DESCRIPTION Dispatcher class for retrieving suggestions. SuggestionEngines must extend Koha::SuggestionEngine::Base, be in the Koha::SuggestionEngine::Plugin namespace, and provide the following methods: B - get suggestions from the plugin for the specified search. These methods may be overriden: B - initialize the plugin B - destroy the plugin These methods should not be overridden unless you are very sure of what you are doing: B - create a new plugin object =head1 FUNCTIONS =cut use strict; use warnings; use Module::Load::Conditional qw( can_load ); use Module::Pluggable::Object; use base qw(Class::Accessor); __PACKAGE__->mk_accessors(qw( schema plugins options record )); =head2 new my $suggestor = Koha::SuggestionEngine->new(%params); Create a new suggestor class. Available parameters are: =over 8 =item B What plugin(s) to use. This must be an arrayref to a list of plugins. Plugins can be specified either with a complete class path, or, if they are in the Koha::SuggestionEngine::Plugin namespace, as only the plugin name, and "Koha::SuggestionEngine::Plugin" will be prepended to it before the plugin is loaded. =back =cut sub new { my $class = shift; my $param = shift; my $options = $param->{options} || ''; my @plugins = (); foreach my $plugin ( @{$param->{plugins}} ) { next unless $plugin; my $plugin_module = $plugin =~ m/:/ ? $plugin : "Koha::SuggestionEngine::Plugin::${plugin}"; if ( can_load( modules => { $plugin_module => undef } ) ) { my $object = $plugin_module->new(); $plugin_module->initialize($param); push @plugins, $object; } } my $self = $class->SUPER::new( { plugins => \@plugins, options => $options } ); bless $self, $class; return $self; } =head2 get_suggestions my $suggestions = $suggester->get_suggestions(\%params) Get a list of suggestions based on the search passed in. Available parameters are: =over 8 =item B Required. The search for which suggestions are desired. =item B Optional. The number of suggestions to retrieve. Defaults to 10. =back =cut sub get_suggestions { my $self = shift; my $param = shift; return unless $param->{'search'}; my $number = $param->{'count'} || 10; my %suggestions; my $index = scalar @{ $self->plugins }; foreach my $pluginobj ( @{ $self->plugins } ) { next unless $pluginobj; my $pluginres = $pluginobj->get_suggestions($param); foreach my $suggestion (@$pluginres) { $suggestions{ $suggestion->{'search'} }->{'relevance'} += $suggestion->{'relevance'} * $index; $suggestions{ $suggestion->{'search'} }->{'label'} |= $suggestion->{'label'}; } $index--; } my @results = (); for ( sort { $suggestions{$b}->{'relevance'} <=> $suggestions{$a}->{'relevance'} } keys %suggestions ) { last if ( $#results == $number - 1 ); push @results, { 'search' => $_, relevance => $suggestions{$_}->{'relevance'}, label => $suggestions{$_}->{'label'} }; } return \@results; } sub DESTROY { my $self = shift; foreach my $pluginobj ( @{ $self->plugins } ) { $pluginobj->destroy(); } } =head2 AvailablePlugins my @available_plugins = Koha::SuggestionEngine::AvailablePlugins(); Get a list of available plugins. =cut sub AvailablePlugins { my $path = 'Koha::SuggestionEngine::Plugin'; my $finder = Module::Pluggable::Object->new( search_path => $path ); return $finder->plugins; } 1;