@@ -, +, @@
apply properly on latest master.
---
C4/Koha.pm | 66 ++++++++++++++++++++
admin/authorised_values.pl | 2 +-
admin/itemtypes.pl | 14 ++++-
installer/data/mysql/kohastructure.sql | 2 +
installer/data/mysql/updatedatabase.pl | 13 ++++
.../prog/en/modules/admin/itemtypes.tt | 32 ++++++++++
.../bootstrap/en/modules/opac-advsearch.tt | 20 +++++-
opac/opac-search.pl | 25 +++++++-
t/db_dependent/Koha.t | 44 ++++++++++++-
9 files changed, 209 insertions(+), 9 deletions(-)
--- a/C4/Koha.pm
+++ a/C4/Koha.pm
@@ -43,6 +43,7 @@ BEGIN {
&subfield_is_koha_internal_p
&GetPrinters &GetPrinter
&GetItemTypes &getitemtypeinfo
+ &GetItemTypesCategorized &GetItemTypesByCategory
&GetSupportName &GetSupportList
&get_itemtypeinfos_of
&getframeworks &getframeworkinfo
@@ -273,6 +274,71 @@ sub GetItemTypes {
}
}
+=head2 GetItemTypesCategorized
+
+ $categories = GetItemTypesCategorized();
+
+Returns a hashref containing search categories.
+A search category will be put in the hash if at least one of its itemtypes is visible in OPAC.
+The categories must be part of Authorized Values (DOCTYPECAT)
+
+=cut
+
+sub GetItemTypesCategorized {
+ my $dbh = C4::Context->dbh;
+ # Order is important, so that partially hidden (some items are not visible in OPAC) search
+ # categories will be visible. hideinopac=0 must be last.
+ my $query = qq|
+ SELECT itemtype, description, imageurl, hideinopac, 0 as 'iscat' FROM itemtypes WHERE ISNULL(searchcategory) or length(searchcategory) = 0
+ UNION
+ SELECT DISTINCT searchcategory AS `itemtype`,
+ authorised_values.lib_opac AS description,
+ authorised_values.imageurl AS imageurl,
+ hideinopac, 1 as 'iscat'
+ FROM itemtypes
+ LEFT JOIN authorised_values ON searchcategory = authorised_value
+ WHERE searchcategory > '' and hideinopac=1
+ UNION
+ SELECT DISTINCT searchcategory AS `itemtype`,
+ authorised_values.lib_opac AS description,
+ authorised_values.imageurl AS imageurl,
+ hideinopac, 1 as 'iscat'
+ FROM itemtypes
+ LEFT JOIN authorised_values ON searchcategory = authorised_value
+ WHERE searchcategory > '' and hideinopac=0
+ |;
+ my $sth = $dbh->prepare($query);
+ $sth->execute;
+
+ my %itemtypes;
+ while ( my $IT = $sth->fetchrow_hashref ) {
+ $itemtypes{ $IT->{'itemtype'} } = $IT;
+ }
+ return ( \%itemtypes );
+}
+
+=head2 GetItemTypesByCategory
+
+ @results = GetItemTypesByCategory( $searchcategory );
+
+Returns the itemtype code of all itemtypes included in a searchcategory.
+
+=cut
+
+sub GetItemTypesByCategory {
+ my ($category) = @_;
+ my $count = 0;
+ my @results;
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT itemtype FROM itemtypes WHERE searchcategory=?");
+ $sth->execute($category);
+
+ while ( my $data = $sth->fetchrow ) {
+ push ( @results, $data );
+ }
+ return @results;
+}
+
sub get_itemtypeinfos_of {
my @itemtypes = @_;
--- a/admin/authorised_values.pl
+++ a/admin/authorised_values.pl
@@ -245,7 +245,7 @@ sub default_form {
}
# push koha system categories
- foreach (qw(Asort1 Asort2 Bsort1 Bsort2 SUGGEST DAMAGED LOST REPORT_GROUP REPORT_SUBGROUP DEPARTMENT TERM SUGGEST_STATUS)) {
+ foreach (qw(Asort1 Asort2 Bsort1 Bsort2 SUGGEST DAMAGED LOST REPORT_GROUP REPORT_SUBGROUP DEPARTMENT TERM SUGGEST_STATUS DOCTYPECAT)) {
push @category_list, $_ unless $categories{$_};
}
--- a/admin/itemtypes.pl
+++ a/admin/itemtypes.pl
@@ -112,6 +112,8 @@ if ( $op eq 'add_form' ) {
$remote_image = $data->{imageurl};
}
+ my $searchcategory = GetAuthorisedValues("DOCTYPECAT", $data->{'searchcategory'});
+
$template->param(
itemtype => $itemtype,
description => $data->{'description'},
@@ -125,6 +127,8 @@ if ( $op eq 'add_form' ) {
imagesets => $imagesets,
remote_image => $remote_image,
sip_media_type => $data->{sip_media_type},
+ hideinopac => $data->{'hideinopac'},
+ searchcategory => $searchcategory,
);
# END $OP eq ADD_FORM
@@ -150,6 +154,8 @@ elsif ( $op eq 'add_validate' ) {
, checkinmsg = ?
, checkinmsgtype = ?
, sip_media_type = ?
+ , hideinopac = ?
+ , searchcategory = ?
WHERE itemtype = ?
';
$sth = $dbh->prepare($query2);
@@ -168,15 +174,17 @@ elsif ( $op eq 'add_validate' ) {
$input->param('checkinmsg'),
$input->param('checkinmsgtype'),
$sip_media_type,
+ $input->param('hideinopac') ? 1 : 0,
+ $input->param('searchcategory'),
$input->param('itemtype')
);
}
else { # add a new itemtype & not modif an old
my $query = "
INSERT INTO itemtypes
- (itemtype,description,rentalcharge, notforloan, imageurl, summary, checkinmsg, checkinmsgtype, sip_media_type)
+ (itemtype,description,rentalcharge, notforloan, imageurl, summary, checkinmsg, checkinmsgtype, sip_media_type, hideinopac, searchcategory)
VALUES
- (?,?,?,?,?,?,?,?,?);
+ (?,?,?,?,?,?,?,?,?,?,?);
";
my $sth = $dbh->prepare($query);
my $image = $input->param('image');
@@ -192,6 +200,8 @@ elsif ( $op eq 'add_validate' ) {
$input->param('checkinmsg'),
$input->param('checkinmsgtype'),
$sip_media_type,
+ $input->param('hideinopac') ? 1 : 0,
+ $input->param('searchcategory'),
);
}
--- a/installer/data/mysql/kohastructure.sql
+++ a/installer/data/mysql/kohastructure.sql
@@ -1276,6 +1276,8 @@ CREATE TABLE `itemtypes` ( -- defines the item types
checkinmsg VARCHAR(255), -- message that is displayed when an item with the given item type is checked in
checkinmsgtype CHAR(16) DEFAULT 'message' NOT NULL, -- type (CSS class) for the checkinmsg, can be "alert" or "message"
sip_media_type VARCHAR(3) DEFAULT NULL, -- SIP2 protocol media type for this itemtype
+ hideinopac tinyint(1) NOT NULL DEFAULT 0, -- Hide the item type from the search options in OPAC
+ searchcategory varchar(20) default NULL, -- Group this item type with others with the same value on OPAC search options
PRIMARY KEY (`itemtype`),
UNIQUE KEY `itemtype` (`itemtype`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--- a/installer/data/mysql/updatedatabase.pl
+++ a/installer/data/mysql/updatedatabase.pl
@@ -9608,6 +9608,19 @@ if ( CheckVersion($DBversion) ) {
SetVersion ($DBversion);
}
+$DBversion = "3.19.00.XXX";
+if ( CheckVersion($DBversion) ) {
+ $dbh->do(q{
+ ALTER TABLE itemtypes
+ ADD hideinopac TINYINT(1) NOT NULL DEFAULT 0
+ AFTER sip_media_type,
+ ADD searchcategory VARCHAR(20) DEFAULT NULL
+ AFTER hideinopac;
+ });
+ print "Upgrade to $DBversion done (Bug 10937 - Option to hide and group itemtypes from advanced search)\n";
+ SetVersion($DBversion);
+}
+
=head1 FUNCTIONS
=head2 TableExists($table)
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/itemtypes.tt
@@ -109,6 +109,25 @@ Item types administration
[% END %]
Required
+
+ Search category
+
+ (Options are defined as the authorized values for the DOCTYPECAT category)
+
+
[% IF ( noItemTypeImages ) %]
Image: Item type images are disabled. To enable them, turn off the noItemTypeImages system preference
[% ELSE %]
@@ -164,6 +183,15 @@ Item types administration
[% END %]
-
+
+ [% IF ( hideinopac ) %]
+
+ [% ELSE %]
+
+ [% END %]
+ (if checked, items of this type will be hidden as filters in OPAC's advanced search)
+
+ -
[% IF ( notforloan ) %]
[% ELSE %]
@@ -260,7 +288,9 @@ Item types administration
[% UNLESS ( noItemTypeImages ) %]
Image | [% END %]
Code |
Description |
+ Search category |
Not for loan |
+ Hide in OPAC |
Charge |
Checkin message |
Actions |
@@ -274,7 +304,9 @@ Item types administration
[% loo.description %] |
+ [% loo.searchcategory %] |
[% IF ( loo.notforloan ) %]Yes[% ELSE %] [% END %] |
+ [% IF ( loo.hideinopac ) %]Yes[% ELSE %] [% END %] |
[% UNLESS ( loo.notforloan ) %]
[% loo.rentalcharge %]
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt
+++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-advsearch.tt
@@ -133,9 +133,25 @@
[% FOREACH itemtypeloo IN advsearchloo.code_loop %]
-
+ [% IF ((!itemtypeloo.searchcategory) AND (itemtypeloo.cat == 0)) OR (itemtypeloo.cat == 1) %]
+
+
+
+
[% IF ( loop.last ) %] [% ELSE %][% UNLESS ( loop.count % 4 ) %][% END %][% END %]
+ [% END %]
[% END %]
--- a/opac/opac-search.pl
+++ a/opac/opac-search.pl
@@ -84,7 +84,7 @@ my ($template,$borrowernumber,$cookie);
my $template_name;
my $template_type = 'basic';
my @params = $cgi->param("limit");
-
+my @searchCategories = $cgi->param('searchcat');
my $format = $cgi->param("format") || '';
my $build_grouped_results = C4::Context->preference('OPACGroupResults');
@@ -194,7 +194,7 @@ my $languages_limit_loop = getLanguages($lang, 1);
$template->param(search_languages_loop => $languages_limit_loop,);
# load the Type stuff
-my $itemtypes = GetItemTypes;
+my $itemtypes = GetItemTypesCategorized;
# the index parameter is different for item-level itemtypes
my $itype_or_itemtype = (C4::Context->preference("item-level_itypes"))?'itype':'itemtype';
my @advancedsearchesloop;
@@ -228,8 +228,13 @@ foreach my $advanced_srch_type (@advanced_search_types) {
code => $thisitemtype,
description => $itemtypes->{$thisitemtype}->{'description'},
imageurl=> getitemtypeimagelocation( 'opac', $itemtypes->{$thisitemtype}->{'imageurl'} ),
+ cat => $itemtypes->{$thisitemtype}->{'iscat'},
+ hideinopac => $itemtypes->{$thisitemtype}->{'hideinopac'},
+ searchcategory => $itemtypes->{$thisitemtype}->{'searchcategory'},
);
- push @itypesloop, \%row;
+ if ( !$itemtypes->{$thisitemtype}->{'hideinopac'} ) {
+ push @itypesloop, \%row;
+ }
}
my %search_code = ( advanced_search_type => $advanced_srch_type,
code_loop => \@itypesloop );
@@ -247,6 +252,7 @@ foreach my $advanced_srch_type (@advanced_search_types) {
ccl => $advanced_srch_type,
code => $thisitemtype->{authorised_value},
description => $thisitemtype->{'lib_opac'} || $thisitemtype->{'lib'},
+ searchcategory => $itemtypes->{$thisitemtype}->{'searchcategory'},
imageurl => getitemtypeimagelocation( 'opac', $thisitemtype->{'imageurl'} ),
);
push @authvalueloop, \%row;
@@ -426,6 +432,19 @@ my @nolimits = $cgi->param('nolimit');
my %is_nolimit = map { $_ => 1 } @nolimits;
@limits = grep { not $is_nolimit{$_} } @limits;
+if (@searchCategories > 0) {
+ my @tabcat;
+ foreach my $typecategory (@searchCategories) {
+ push (@tabcat, GetItemTypesByCategory($typecategory));
+ }
+
+ foreach my $itemtypeInCategory (@tabcat) {
+ push (@limits, "mc-$itype_or_itemtype,phr:".$itemtypeInCategory);
+ }
+}
+
+@limits = map { uri_unescape($_) } @limits;
+
if($params->{'multibranchlimit'}) {
my $multibranch = '('.join( " or ", map { "branch: $_ " } @{ GetBranchesInCategory( $params->{'multibranchlimit'} ) } ).')';
push @limits, $multibranch if ($multibranch ne '()');
--- a/t/db_dependent/Koha.t
+++ a/t/db_dependent/Koha.t
@@ -7,12 +7,13 @@ use strict;
use warnings;
use C4::Context;
use Koha::DateUtils qw(dt_from_string);
+use Data::Dumper;
use Test::More tests => 8;
use DateTime::Format::MySQL;
BEGIN {
- use_ok('C4::Koha', qw( :DEFAULT GetDailyQuote ));
+ use_ok('C4::Koha', qw( :DEFAULT GetDailyQuote GetItemTypesByCategory GetItemTypesCategorized));
use_ok('C4::Members');
}
@@ -305,4 +306,45 @@ subtest 'GetFrameworksLoop() tests' => sub {
);
};
+subtest 'GetItemTypesByCategory GetItemTypesCategorized test' => sub{
+ plan tests => 7;
+
+ my $insertGroup = AddAuthorisedValue('DOCTYPECAT', 'Qwertyware');
+ ok($insertGroup, "Create group Qwertyware");
+
+ my $query = "INSERT into itemtypes (itemtype, description, searchcategory, hideinopac) values (?,?,?,?)";
+ my $insertSth = C4::Context->dbh->prepare($query);
+ $insertSth->execute('BKghjklo1', 'One type of book', '', 0);
+ $insertSth->execute('BKghjklo2', 'Another type of book', 'Qwertyware', 0);
+ $insertSth->execute('BKghjklo3', 'Yet another type of book', 'Qwertyware', 0);
+
+ # Azertyware should not exist.
+ my @results = GetItemTypesByCategory('Azertyware');
+ is(scalar @results, 0, 'GetItemTypesByCategory: Invalid category returns nothing');
+
+ @results = GetItemTypesByCategory('Qwertyware');
+ my @expected = ( 'BKghjklo2', 'BKghjklo3' );
+ is_deeply(\@results,\@expected,'GetItemTypesByCategory: valid category returns itemtypes');
+
+ # add more data since GetItemTypesCategorized's search is more subtle
+ $insertGroup = AddAuthorisedValue('DOCTYPECAT', 'Veryveryheavybook');
+ $insertSth->execute('BKghjklo4', 'Another hidden book', 'Veryveryheavybook', 1);
+
+ my $hrCat = GetItemTypesCategorized();
+ ok(exists $hrCat->{Qwertyware}, 'GetItemTypesCategorized: fully visible category exists');
+ ok($hrCat->{Veryveryheavybook} &&
+ $hrCat->{Veryveryheavybook}->{hideinopac}==1, 'GetItemTypesCategorized: non-visible category hidden' );
+
+ $insertSth->execute('BKghjklo5', 'An hidden book', 'Qwertyware', 1);
+ $hrCat = GetItemTypesCategorized();
+ ok(exists $hrCat->{Qwertyware}, 'GetItemTypesCategorized: partially visible category exists');
+
+ my @only = ( 'BKghjklo1', 'BKghjklo2', 'BKghjklo3', 'BKghjklo4', 'BKghjklo5', 'Qwertyware', 'Veryveryheavybook' );
+ @results = ();
+ foreach my $key (@only) {
+ push @results, $key if exists $hrCat->{$key};
+ }
+ @expected = ( 'BKghjklo1', 'Qwertyware', 'Veryveryheavybook' );
+ is_deeply(\@results,\@expected, 'GetItemTypesCategorized: grouped and ungrouped items returned as expected.');
+}
$dbh->rollback();
--
|