From dd7ef22cf40422cfe13208153d1042589930283a Mon Sep 17 00:00:00 2001 From: Jesse Weaver Date: Wed, 29 May 2013 14:59:57 -0600 Subject: [PATCH] Bug 10486 - Allow external Z39.50 targets to be searched from the OPAC This adds a new page to the OPAC that can search several Z39.50 targets using Pazpar2. Test plan: 1) Apply patches. 2) Update database. 3) Add one or more Z39.50 targets, using the Administration -> External targets screen. Note that not all targets support keyword search, but here are some that do: * Library of Congress: lx2.loc.gov, 210, LCDB, none, none, MARC21, UTF-8 * BNF2: z3950.bnf.fr, 2211, TOUT, Z3950, Z3950_BNF, UNIMARC, UTF-8 4) Perform a search on the OPAC, check to see if the "external targets" notice pops up at the top. 5) Click on the results link near that message. 6) This should bring back results from all enabled targets, all of which should be clickable to bring up a detailed view of the record. (This version fixes some typos and accidental changes.) Signed-off-by: Chris Cormack --- C4/Search.pm | 30 + C4/XSLT.pm | 24 +- Makefile.PL | 2 +- admin/external_targets.pl | 125 +++ etc/koha-conf.xml | 13 - etc/koha-httpd.conf | 15 +- etc/pazpar2/generic-settings.xml | 21 + etc/pazpar2/pazpar2.xml | 2 +- etc/pazpar2/unimarc-work-groups.xsl | 98 ++ installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 33 + .../intranet-tmpl/prog/en/css/staff-global.css | 14 + .../intranet-tmpl/prog/en/includes/admin-menu.inc | 1 + .../prog/en/modules/admin/admin-home.tt | 2 + .../prog/en/modules/admin/external-targets.tt | 180 ++++ .../prog/en/modules/admin/preferences/opac.pref | 7 + koha-tmpl/opac-tmpl/ccsr/en/css/opac.css | 16 + koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js | 106 ++ .../en/lib/jquery/plugins/jquery.lightbox_me.js | 254 +++++ koha-tmpl/opac-tmpl/lib/pz2.js | 1110 ++++++++++++++++++++ koha-tmpl/opac-tmpl/prog/en/css/opac.css | 27 +- koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js | 106 ++ .../en/lib/jquery/plugins/jquery.lightbox_me.js | 254 +++++ .../prog/en/modules/opac-external-search.tt | 240 +++++ .../opac-tmpl/prog/en/modules/opac-results.tt | 59 +- .../prog/en/xslt/MARC21slim2OPACResults.xsl | 6 +- .../opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl | 2 +- .../prog/en/xslt/UNIMARCslim2OPACResults.xsl | 3 + opac/opac-external-search.pl | 63 ++ opac/opac-search.pl | 12 +- opac/svc/pazpar2_init | 99 ++ rewrite-config.PL | 8 +- 32 files changed, 2888 insertions(+), 45 deletions(-) create mode 100755 admin/external_targets.pl create mode 100644 etc/pazpar2/generic-settings.xml create mode 100644 etc/pazpar2/unimarc-work-groups.xsl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt create mode 100644 koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js create mode 100644 koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js create mode 100644 koha-tmpl/opac-tmpl/lib/pz2.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.lightbox_me.js create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-external-search.tt create mode 100755 opac/opac-external-search.pl create mode 100755 opac/svc/pazpar2_init diff --git a/C4/Search.pm b/C4/Search.pm index dd844e3..9bda56e 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -72,6 +72,7 @@ This module provides searching functions for Koha's bibliographic databases &GetDistinctValues &enabled_staff_search_views &PurgeSearchHistory + &GetExternalSearchTargets ); # make all your functions, whether exported or not; @@ -2367,6 +2368,35 @@ sub _ZOOM_event_loop { } } +=head2 GetExternalSearchTargets + +Returns the list of Z39.50 servers that are marked for search in the OPAC using +Pazpar2. + +=cut + +sub GetExternalSearchTargets { + my ( $branchcode ) = @_; + + if ( $branchcode ) { + return C4::Context->dbh->selectall_arrayref( q{ + SELECT * FROM external_targets et + LEFT JOIN external_target_restrictions etr + ON (etr.target_id = et.target_id and etr.branchcode = ?) + WHERE etr.target_id IS NULL + ORDER BY et.name + }, { Slice => {} }, $branchcode ); + } else { + return C4::Context->dbh->selectall_arrayref( q{ + SELECT * FROM external_targets et + LEFT JOIN external_target_restrictions etr USING (target_id) + GROUP by et.target_id + HAVING branchcode IS NULL + ORDER BY et.name + }, { Slice => {} } ); + } +} + END { } # module clean-up code here (global destructor) diff --git a/C4/XSLT.pm b/C4/XSLT.pm index d85b048..7ebac8a 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -42,6 +42,7 @@ BEGIN { $VERSION = 3.07.00.049; @ISA = qw(Exporter); @EXPORT = qw( + &XSLTGetFilename &XSLTParse4Display &GetURI ); @@ -156,9 +157,10 @@ sub _get_best_default_xslt_filename { return $xslfilename; } -sub XSLTParse4Display { - my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; - my $xslfilename = C4::Context->preference($xslsyspref); +sub XSLTGetFilename { + my ( $marcflavour, $xslsyspref ) = @_; + + my $xslfilename = $marcflavour eq C4::Context->preference('marcflavour') ? C4::Context->preference($xslsyspref) : 'default'; if ( $xslfilename =~ /^\s*"?default"?\s*$/i ) { my $htdocs; my $theme; @@ -167,22 +169,22 @@ sub XSLTParse4Display { if ($xslsyspref eq "XSLTDetailsDisplay") { $htdocs = C4::Context->config('intrahtdocs'); $theme = C4::Context->preference("template"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2intranetDetail.xsl"; } elsif ($xslsyspref eq "XSLTResultsDisplay") { $htdocs = C4::Context->config('intrahtdocs'); $theme = C4::Context->preference("template"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2intranetResults.xsl"; } elsif ($xslsyspref eq "OPACXSLTDetailsDisplay") { $htdocs = C4::Context->config('opachtdocs'); $theme = C4::Context->preference("opacthemes"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2OPACDetail.xsl"; } elsif ($xslsyspref eq "OPACXSLTResultsDisplay") { $htdocs = C4::Context->config('opachtdocs'); $theme = C4::Context->preference("opacthemes"); - $xslfile = C4::Context->preference('marcflavour') . + $xslfile = $marcflavour . "slim2OPACResults.xsl"; } $xslfilename = _get_best_default_xslt_filename($htdocs, $theme, $lang, $xslfile); @@ -193,6 +195,14 @@ sub XSLTParse4Display { $xslfilename =~ s/\{langcode\}/$lang/; } + return $xslfilename; +} + +sub XSLTParse4Display { + my ( $biblionumber, $orig_record, $xslsyspref, $fixamps, $hidden_items ) = @_; + + my $xslfilename = XSLTGetFilename( C4::Context->preference( 'marcflavour' ), $xslsyspref ); + # grab the XML, run it through our stylesheet, push it out to the browser my $record = transformMARCXML4XSLT($biblionumber, $orig_record); #return $record->as_formatted(); diff --git a/Makefile.PL b/Makefile.PL index 66f9a0f..07f16e8 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -536,7 +536,7 @@ if ($config{'INSTALL_ZEBRA'} eq "yes") { ); if ($config{'INSTALL_PAZPAR2'} eq 'yes') { push @{ $pl_files->{'rewrite-config.PL'} }, ( - 'blib/PAZPAR2_CONF_DIR/koha-biblios.xml', + 'blib/PAZPAR2_CONF_DIR/generic-settings.xml', 'blib/PAZPAR2_CONF_DIR/pazpar2.xml' ); } diff --git a/admin/external_targets.pl b/admin/external_targets.pl new file mode 100755 index 0000000..0fc9037 --- /dev/null +++ b/admin/external_targets.pl @@ -0,0 +1,125 @@ +#!/usr/bin/perl +# +# Copyright 2013 Jesse Weaver +# +# 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 2 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +use Modern::Perl '2010'; + +use CGI; + +use C4::Auth; +use C4::Context; +use C4::Branch; +use C4::Output; +use URI::Escape; + +our $dbh = C4::Context->dbh; +our $input = new CGI; + +our ( $template, $loggedinuser, $cookie ) = get_template_and_user( { + template_name => "admin/external-targets.tt", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => {parameters => 'parameters_remaining_permissions'}, + debug => 1, +} ); + +our $op = $input->param( 'op' ) // 'show'; +$template->{VARS}->{op} = $op; + +given ( $op ) { + when ( 'show' ) { show_external_targets(); } + when ( 'add' ) { show_edit_form(); } + when ( 'edit' ) { show_edit_form(); } + when ( 'save' ) { save_target(); } + when ( 'delete' ) { delete_target(); } +} + +output_html_with_http_headers $input, $cookie, $template->output; + +sub show_external_targets { + $template->{VARS}->{saved_id} = $input->param( 'saved_id' ); + $template->{VARS}->{deleted_name} = $input->param( 'deleted_name' ); + $template->{VARS}->{targets} = $dbh->selectall_arrayref( q{ + SELECT * + FROM external_targets + }, { Slice => {} } ); +} + +sub show_edit_form { + $template->{VARS}->{branches} = GetBranchesLoop( undef, 0 ); + $template->{VARS}->{syntaxes} = [ 'MARC21', 'UNIMARC', 'NORMARC' ]; + $template->{VARS}->{encodings} = { 'utf8' => 'UTF-8', 'marc8' => 'MARC-8' }; + + my $target_id; + if ( $target_id = $input->param( 'target_id' ) ) { + $template->{VARS}->{target} = $dbh->selectrow_hashref( q{ SELECT * FROM external_targets WHERE target_id = ? }, {}, $target_id ); + + my $available_branches = $dbh->selectall_hashref( q{ SELECT * FROM external_target_restrictions WHERE target_id = ? }, 'branchcode', {}, $target_id ); + + foreach my $branch ( @{ $template->{VARS}->{branches} } ) { + $branch->{selected} = 1 if ( $available_branches->{$branch->{branchcode}} ); + } + } +} + +sub save_target { + my $target_id; + if ( $target_id = $input->param( 'target_id' ) ) { + $dbh->do( q{ + UPDATE external_targets + SET name = ?, host = ?, port = ?, db = ?, userid = ?, password = ?, syntax = ?, encoding = ? + WHERE target_id = ? + }, {}, map { $input->param( $_ ) // '' } qw( name host port db userid password syntax encoding target_id ) ); + } else { + $dbh->do( q{ + INSERT + INTO external_targets(name, host, port, db, userid, password, syntax, encoding) + VALUES(?, ?, ?, ?, ?, ?, ?, ?) + }, {}, map { $input->param( $_ ) // '' } qw( name host port db userid password syntax encoding ) ); + $target_id = $dbh->last_insert_id( undef, undef, undef, undef ); + } + + $dbh->do( q{ + DELETE + FROM external_target_restrictions + WHERE target_id = ? + }, {}, $target_id ); + + foreach my $branchcode ( $input->param( 'branch' ) ) { + $dbh->do( q{ + INSERT + INTO external_target_restrictions(branchcode, target_id) + VALUES(?, ?) + }, {}, $branchcode, $target_id ); + } + + print $input->redirect( '/cgi-bin/koha/admin/external_targets.pl?saved_id=' . $target_id ); + exit; +} + +sub delete_target { + my ($target_id, $target); + + return unless ( $target_id = $input->param( 'target_id' ) and $target = $dbh->selectrow_hashref( q{ SELECT * FROM external_targets WHERE target_id = ? }, {}, $target_id ) ); + + $dbh->do( q{ DELETE FROM external_targets WHERE target_id = ? }, {}, $target_id ); + + print $input->redirect( '/cgi-bin/koha/admin/external_targets.pl?deleted_name=' . uri_escape( $target->{'name'} ) ); +} diff --git a/etc/koha-conf.xml b/etc/koha-conf.xml index d42f041..7ccf215 100644 --- a/etc/koha-conf.xml +++ b/etc/koha-conf.xml @@ -19,19 +19,6 @@ tcp:@:__ZEBRA_SRU_BIBLIOS_PORT__ --> - -__PAZPAR2_TOGGLE_XML_PRE__ -tcp:@:__MERGE_SERVER_PORT__ - - __ZEBRA_DATA_DIR__/biblios - __ZEBRA_CONF_DIR__/__ZEBRA_BIB_CFG__ - __ZEBRA_CONF_DIR__/pqf.properties - -__PAZPAR2_TOGGLE_XML_POST__ - __ZEBRA_DATA_DIR__/biblios diff --git a/etc/koha-httpd.conf b/etc/koha-httpd.conf index f9a1970..df3dae1 100644 --- a/etc/koha-httpd.conf +++ b/etc/koha-httpd.conf @@ -32,7 +32,7 @@ # Secure internal stuff - + Order deny,allow Deny from all @@ -113,6 +113,17 @@ RewriteRule ^/isbn/([^\/]*)/?$ /search?q=isbn:$1 [PT] RewriteRule ^/issn/([^\/]*)/?$ /search?q=issn:$1 [PT] + + __PAZPAR2_TOGGLE_HTTPD_PRE__ + + AddDefaultCharset off + Order deny,allow + Allow from all + + + ProxyRequests off + ProxyPass /pazpar2/search.pz2 http://__PAZPAR2_HOST__:__PAZPAR2_PORT__/search.pz2 + __PAZPAR2_TOGGLE_HTTPD_POST__ ## Intranet @@ -149,7 +160,7 @@ # Secure internal stuff - + Order deny,allow Deny from all diff --git a/etc/pazpar2/generic-settings.xml b/etc/pazpar2/generic-settings.xml new file mode 100644 index 0000000..5d56b99 --- /dev/null +++ b/etc/pazpar2/generic-settings.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/etc/pazpar2/pazpar2.xml b/etc/pazpar2/pazpar2.xml index 2269647..a3a3404 100644 --- a/etc/pazpar2/pazpar2.xml +++ b/etc/pazpar2/pazpar2.xml @@ -4,7 +4,7 @@ - + diff --git a/etc/pazpar2/unimarc-work-groups.xsl b/etc/pazpar2/unimarc-work-groups.xsl new file mode 100644 index 0000000..50cbe3c --- /dev/null +++ b/etc/pazpar2/unimarc-work-groups.xsl @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index a07103a..f9d6a88 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -256,6 +256,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('OpacRenewalAllowed','0',NULL,'If ON, users can renew their issues directly from their OPAC account','YesNo'), ('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|null','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'), ('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'), +('OPACSearchExternalTargets','0',NULL,'Whether to search external targets in the OPAC','YesNo'), ('OPACSearchForTitleIn','
  • Other Libraries (WorldCat)
  • \n
  • Other Databases (Google Scholar)
  • \n
  • Online Stores (Bookfinder.com)
  • \n
  • Open Library (openlibrary.org)
  • ','70|10','Enter the HTML that will appear in the \'Search for this title in\' box on the detail page in the OPAC. Enter {TITLE}, {AUTHOR}, or {ISBN} in place of their respective variables in the URL. Leave blank to disable \'More Searches\' menu.','Textarea'), ('OpacSeparateHoldings','0',NULL,'Separate current branch holdings from other holdings (OPAC)','YesNo'), ('OpacSeparateHoldingsBranch','homebranch','homebranch|holdingbranch','Branch used to separate holdings (OPAC)','Choice'), diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index e6f54f9..64be813 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -7762,6 +7762,39 @@ if ( CheckVersion($DBversion) ) { SetVersion ($DBversion); } +$DBversion = "3.15.00.XXX"; +if(CheckVersion($DBversion)) { + $dbh->do( +"INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('OPACSearchExternalTargets','0','Whether to search external targets in the OPAC','','YesNo')" + ); + $dbh->do( q{ +CREATE TABLE `external_targets` ( + `target_id` int(11) NOT NULL AUTO_INCREMENT, + `host` varchar(128) NOT NULL, + `port` int(11) NOT NULL, + `db` varchar(64) NOT NULL, + `userid` varchar(64) DEFAULT '', + `password` varchar(64) DEFAULT '', + `name` varchar(64) NOT NULL, + `syntax` varchar(64) NOT NULL, + `encoding` varchar(16) DEFAULT 'MARC-8', + PRIMARY KEY (`target_id`) +) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 + } ); + $dbh->do( q{ +CREATE TABLE `external_target_restrictions` ( + `branchcode` varchar(10) NOT NULL, + `target_id` int(11) NOT NULL, + KEY `branchcode` (`branchcode`), + KEY `target_id` (`target_id`), + CONSTRAINT `external_target_restrictions_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE, + CONSTRAINT `external_target_restrictions_ibfk_2` FOREIGN KEY (`target_id`) REFERENCES `external_targets` (`target_id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 + } ); + print "Upgrade to $DBversion done (Bug 10486 - Allow external Z39.50 targets to be searched from the OPAC)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css index 755a02a..89c47d6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css +++ b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css @@ -270,6 +270,16 @@ tr.even td, tr.even.highlight td { border-right : 1px solid #BCBCBC; } +tr.highlight td { + background-color : #F6F6F6; + border-color : #BCBCBC; +} + +tr.highlight th[scope=row] { + background-color : #DDDDDD; + border-color : #BCBCBC; +} + td.od { color : #cc0000; font-weight : bold; @@ -287,6 +297,10 @@ tr.odd.onissue td { background-color: #FFFFE1; } +tr.updated td { + background-color: #FFFFBB; +} + tfoot td { background-color : #f3f3f3; font-weight : bold; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc index 91878bf..486581c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc @@ -46,6 +46,7 @@
  • Classification sources
  • Record matching rules
  • OAI sets configuration
  • +
  • External search targets
  • Acquisition parameters
    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt index 46a3b3a..aac3b19 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt @@ -84,6 +84,8 @@
    Search engine configuration
    Manage indexes, facets, and their mappings to MARC fields and subfields.
    [% END %] +
    External search targets
    +
    Define external search targets that can be searched from the OPAC.

    Acquisition parameters

    diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt new file mode 100644 index 0000000..92d1595 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/external-targets.tt @@ -0,0 +1,180 @@ +[% INCLUDE 'doc-head-open.inc' %] +[% IF op == 'show' %] +Koha › Administration › External targets +[% ELSIF op == 'add' %] +Koha › Administration › External targets › Create an external target +[% ELSIF op == 'edit' %] +Koha › Administration › External targets › Editing '[% target.name %]' +[% END %] +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'datatables-strings.inc' %] + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'cat-search.inc' %] + +[% IF op == 'show' %] + + + +[% ELSIF op == 'add' %] + + + +[% ELSIF op == 'edit' %] + + + +[% END %] + +
    +
    + +
    + +[% IF op == 'show' %] + +[% IF deleted_name %] +
    +

    Deleted target '[% deleted_name %]'

    +
    +[% END %] + + + +

    These Z39.50 targets are searched in the OPAC using the "external targets" feature. Note that Pazpar2 must be installed and configured for this to work.

    + +[% IF targets.size %] + + + + [% FOREACH target = targets %] + + + + + + + + + + [% END %] + +
    NameConnectionLoginSyntaxEncoding  
    [% target.name %][% target.host %]:[% target.port %]/[% target.db %][% IF target.userid %][% target.userid %] / [% IF target.password %]********[% ELSE %]none[% END %][% ELSE %]none[% END %][% target.syntax %] + [% IF target.encoding == 'marc8' %] + MARC-8 + [% ELSIF target.encoding == 'utf8' %] + UTF-8 + [% END %] + EditDelete
    +[% ELSE %] +

    No external targets have been defined yet.

    +[% END %] + +[% ELSIF op == 'add' || op == 'edit' %] + +
    + [% IF op == 'add' %] +

    Create an external target

    + [% ELSIF op == 'edit' %] +

    Editing '[% target.name %]'

    + [% END %] + + + + +
    +
      +
    1. +
    2. +
    3. +
    4. +
    5. +
    6. +
    7. + + +
    8. +
    9. + + +
    10. +
    11. + +
      + Not available to patrons from: +

      Only targets with no restrictions will be shown to anonymous (not logged in) users.

      +
        + [% FOREACH branch = branches %] +
      1. + + [% IF branch.selected %] + + [% ELSE %] + + [% END %] +
      2. + [% END %] +
      +
      +
    12. +
    +
    + +
    +
    + +[% END %] + +
    +
    +[% INCLUDE 'admin-menu.inc' %] +
    + +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index a75c7ef..368b314 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -424,6 +424,13 @@ OPAC: yes: Allow no: Do not allow - users to add a note when placing a hold. + - + - pref: OPACSearchExternalTargets + default: 0 + choices: + yes: Search + no: "Don't search" + - external targets from the OPAC. Policy: - diff --git a/koha-tmpl/opac-tmpl/ccsr/en/css/opac.css b/koha-tmpl/opac-tmpl/ccsr/en/css/opac.css index 0901d6b..698968d 100644 --- a/koha-tmpl/opac-tmpl/ccsr/en/css/opac.css +++ b/koha-tmpl/opac-tmpl/ccsr/en/css/opac.css @@ -1609,6 +1609,10 @@ strong em, em strong { vertical-align: top; width: 10px; } +.sourcecol { + vertical-align: top; + width: 100px; +} #container { color : #000; } @@ -2876,3 +2880,15 @@ a.reviewlink,a.reviewlink:visited { display: block; overflow: auto; } + +#modal-overlay { + background-color: white; + border-radius: 5px; + max-width: 75%; + padding: 15px; +} + +#overdrive-results, #pazpar2-results { + font-weight: bold; + padding-left: 1em; +} diff --git a/koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js b/koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js new file mode 100644 index 0000000..b2fe4a7 --- /dev/null +++ b/koha-tmpl/opac-tmpl/ccsr/en/js/externalsearch.js @@ -0,0 +1,106 @@ +if ( typeof KOHA == "undefined" || !KOHA ) { + var KOHA = {}; +} + +KOHA.XSLTGet = ( function() { + // Horrible browser hack, but required due to the following hard-to-detect and long-unfixed bug: + // https://bugs.webkit.org/show_bug.cgi?id=60276 + var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); + var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor); + + if ( !isChrome && !isSafari ) return $.get; + + return function( url ) { + var result = new jQuery.Deferred(); + var basepath = url.match( /(.*\/)*/ )[0]; + + $.get( url ).done( function( xslDoc ) { + var xslImports = xslDoc.getElementsByTagNameNS( 'http://www.w3.org/1999/XSL/Transform', 'import' ); + var importsRemaining = xslImports.length; + + if ( importsRemaining == 0 ) { + result.resolve( xslDoc ); + return; + } + + $.each( xslImports, function( i, importElem ) { + var path = $( importElem ).attr( 'href' ); + if ( !/^(\/|https?:)/.test( path ) ) path = basepath + path; + + KOHA.XSLTGet( path ).done( function( subDoc ) { + importsRemaining--; + $( importElem ).replaceWith( subDoc.documentElement.childNodes ); + + if ( importsRemaining == 0 ) result.resolve( xslDoc ); + } ).fail( function() { + importsRemaining = -1; + + result.reject(); + } ); + } ); + } ).fail( function() { + result.reject(); + } ); + + return result; + }; +} )(); + +KOHA.TransformToFragment = function( xmlDoc, xslDoc ) { + if ( window.XSLTProcessor ) { + var proc = new XSLTProcessor(); + proc.importStylesheet( xslDoc ); + proc.setParameter( null, 'showAvailability', false ); + return (new XMLSerializer).serializeToString( proc.transformToFragment( xmlDoc, document ) ); + } else if ( window.ActiveXObject ) { + var xslt = new ActiveXObject( "Msxml2.XSLTemplate" ); + xslt.stylesheet = xslDoc; + var xslProc = xslt.createProcessor(); + xslProc.input = xmlDoc; + xslProc.addParameter( 'showAvailability', false ); + xslProc.transform(); + return xslProc.output; + } +}; + +KOHA.ExternalSearch = ( function() { + return { + targets: {}, + Search: function( q, limit, callback ) { + var targetIDs = []; + var includedTargets = []; + + $.each( KOHA.ExternalSearch.targets, function ( url, info ) { + if ( !info.disabled ) { + includedTargets.push( url ); + targetIDs.push( info.id ); + } + } ); + + if ( KOHA.ExternalSearch._pz !== undefined ) { + afterinit( KOHA.ExternalSearch._pz ); + } else { + $.get( '/cgi-bin/koha/svc/pazpar2_init', { targets: targetIDs.join(',') }, function( data ) { + KOHA.ExternalSearch._pz = new pz2({ + sessionId: data.sessionID, + onshow: callback, + errorhandler: function ( error ) { callback( { error: error } ) }, + } ); + afterinit( KOHA.ExternalSearch._pz ); + } ); + } + + function afterinit( pz ) { + pz.search( q, limit, 'relevance:0', 'pz:id=' + includedTargets.join( '|' ) ); + } + }, + Fetch: function( offset, callback ) { + var pz = KOHA.ExternalSearch._pz; + pz.showCallback = callback; + pz.show( offset ); + }, + GetDetailedRecord: function( recid, callback ) { + KOHA.ExternalSearch._pz.record( recid, 0, undefined, { callback: callback } ); + }, + }; +} )(); diff --git a/koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js b/koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js new file mode 100644 index 0000000..effe8a6 --- /dev/null +++ b/koha-tmpl/opac-tmpl/ccsr/en/lib/jquery/plugins/jquery.lightbox_me.js @@ -0,0 +1,254 @@ +/* +* $ lightbox_me +* By: Buck Wilson +* Version : 2.3 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +(function($) { + + $.fn.lightbox_me = function(options) { + + return this.each(function() { + + var + opts = $.extend({}, $.fn.lightbox_me.defaults, options), + $overlay = $(), + $self = $(this), + $iframe = $('