Bug 10961: Error in GetMarcBiblio can cause severe data loss
[koha.git] / Koha / SuggestionEngine.pm
blobee1b2cc869565a110db29b04f8fa828cd9a66e77
1 package Koha::SuggestionEngine;
3 # Copyright 2012 C & P Bibliography Services
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 =head1 NAME
22 Koha::SuggestionEngine - Dispatcher class for suggestion engines
24 =head1 SYNOPSIS
26 use Koha::SuggestionEngine;
27 my $suggestor = Koha::SuggestionEngine->new(%params);
28 $suggestor->get_suggestions($search)
30 =head1 DESCRIPTION
32 Dispatcher class for retrieving suggestions. SuggestionEngines must
33 extend Koha::SuggestionEngine::Base, be in the Koha::SuggestionEngine::Plugin
34 namespace, and provide the following methods:
36 B<get_suggestions ($search)> - get suggestions from the plugin for the
37 specified search.
39 These methods may be overriden:
41 B<initialize (%params)> - initialize the plugin
43 B<destroy ()> - destroy the plugin
45 These methods should not be overridden unless you are very sure of what
46 you are doing:
48 B<new ()> - create a new plugin object
50 =head1 FUNCTIONS
52 =cut
54 use strict;
55 use warnings;
56 use Module::Load::Conditional qw(can_load);
57 use Module::Pluggable::Object;
59 use base qw(Class::Accessor);
61 __PACKAGE__->mk_accessors(qw( schema plugins options record ));
63 =head2 new
65 my $suggestor = Koha::SuggestionEngine->new(%params);
67 Create a new suggestor class. Available parameters are:
69 =over 8
71 =item B<plugins>
73 What plugin(s) to use. This must be an arrayref to a list of plugins. Plugins
74 can be specified either with a complete class path, or, if they are in the
75 Koha::SuggestionEngine::Plugin namespace, as only the plugin name, and
76 "Koha::SuggestionEngine::Plugin" will be prepended to it before the plugin
77 is loaded.
79 =back
81 =cut
83 sub new {
84 my $class = shift;
85 my $param = shift;
87 my $options = $param->{options} || '';
88 my @plugins = ();
90 foreach my $plugin ( @{$param->{plugins}} ) {
91 next unless $plugin;
92 my $plugin_module =
93 $plugin =~ m/:/
94 ? $plugin
95 : "Koha::SuggestionEngine::Plugin::${plugin}";
96 if ( can_load( modules => { $plugin_module => undef } ) ) {
97 my $object = $plugin_module->new();
98 $plugin_module->initialize($param);
99 push @plugins, $object;
103 my $self = $class->SUPER::new(
105 plugins => \@plugins,
106 options => $options
109 bless $self, $class;
110 return $self;
113 =head2 get_suggestions
115 my $suggestions = $suggester->get_suggestions(\%params)
117 Get a list of suggestions based on the search passed in. Available parameters
118 are:
120 =over 8
122 =item B<search>
124 Required. The search for which suggestions are desired.
126 =item B<count>
128 Optional. The number of suggestions to retrieve. Defaults to 10.
130 =back
132 =cut
134 sub get_suggestions {
135 my $self = shift;
136 my $param = shift;
138 return unless $param->{'search'};
140 my $number = $param->{'count'} || 10;
142 my %suggestions;
144 my $index = scalar @{ $self->plugins };
146 foreach my $pluginobj ( @{ $self->plugins } ) {
147 next unless $pluginobj;
148 my $pluginres = $pluginobj->get_suggestions($param);
149 foreach my $suggestion (@$pluginres) {
150 $suggestions{ $suggestion->{'search'} }->{'relevance'} +=
151 $suggestion->{'relevance'} * $index;
152 $suggestions{ $suggestion->{'search'} }->{'label'} |=
153 $suggestion->{'label'};
155 $index--;
158 my @results = ();
159 for (
160 sort {
161 $suggestions{$b}->{'relevance'} <=> $suggestions{$a}->{'relevance'}
162 } keys %suggestions
165 last if ( $#results == $number - 1 );
166 push @results,
168 'search' => $_,
169 relevance => $suggestions{$_}->{'relevance'},
170 label => $suggestions{$_}->{'label'}
174 return \@results;
177 sub DESTROY {
178 my $self = shift;
180 foreach my $pluginobj ( @{ $self->plugins } ) {
181 $pluginobj->destroy();
185 =head2 AvailablePlugins
187 my @available_plugins = Koha::SuggestionEngine::AvailablePlugins();
189 Get a list of available plugins.
191 =cut
193 sub AvailablePlugins {
194 my $path = 'Koha::SuggestionEngine::Plugin';
195 my $finder = Module::Pluggable::Object->new( search_path => $path );
196 return $finder->plugins;