Bugzilla – Attachment 21687 Details for
Bug 10486
Allow external Z39.50 targets to be searched from the OPAC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 10486 - Allow external Z39.50 targets to be searched from the OPAC
Bug-10486---Allow-external-Z3950-targets-to-be-sea.patch (text/plain), 174.67 KB, created by
Jesse Weaver
on 2013-09-30 23:24:34 UTC
(
hide
)
Description:
Bug 10486 - Allow external Z39.50 targets to be searched from the OPAC
Filename:
MIME Type:
Creator:
Jesse Weaver
Created:
2013-09-30 23:24:34 UTC
Size:
174.67 KB
patch
obsolete
>From 85ce1a1f5e591e255598516a4be8cb68da0314de Mon Sep 17 00:00:00 2001 >From: Jesse Weaver <pianohacker@gmail.com> >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. >--- > C4/Search.pm | 31 +- > 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 | 218 ++++ > installer/data/mysql/updatedatabase.pl | 33 + > .../intranet-tmpl/prog/en/css/staff-global.css | 24 +- > .../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, 3105 insertions(+), 56 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 0453b91..91f838a 100644 >--- a/C4/Search.pm >+++ b/C4/Search.pm >@@ -71,7 +71,7 @@ This module provides searching functions for Koha's bibliographic databases > &AddSearchHistory > &GetDistinctValues > &enabled_staff_search_views >- &PurgeSearchHistory >+ &GetExternalSearchTargets > ); > > # make all your functions, whether exported or not; >@@ -2359,6 +2359,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 57bb108..8ad84b2 100644 >--- a/Makefile.PL >+++ b/Makefile.PL >@@ -535,7 +535,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 @@ > <listen id="publicserver" >tcp:@:__ZEBRA_SRU_BIBLIOS_PORT__</listen> > --> > >-<!-- Settings for special biblio server instance for PazPar2. >- Because PazPar2 only connects to a Z39.50 server using TCP/IP, >- it cannot use the Unix-domain socket that biblioserver uses. >- Therefore, a custom server is defined. --> >-__PAZPAR2_TOGGLE_XML_PRE__ >-<listen id="mergeserver">tcp:@:__MERGE_SERVER_PORT__</listen> >-<server id="mergeserver" listenref="mergeserver"> >- <directory>__ZEBRA_DATA_DIR__/biblios</directory> >- <config>__ZEBRA_CONF_DIR__/__ZEBRA_BIB_CFG__</config> >- <cql2rpn>__ZEBRA_CONF_DIR__/pqf.properties</cql2rpn> >-</server> >-__PAZPAR2_TOGGLE_XML_POST__ >- > <!-- BIBLIOGRAPHIC RECORDS --> > <server id="biblioserver" listenref="biblioserver"> > <directory>__ZEBRA_DATA_DIR__/biblios</directory> >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 @@ > </Directory> > > # Secure internal stuff >- <DirectoryMatch "__OPAC_WWW_DIR__/.*/(modules|xslt|includes)"> >+ <DirectoryMatch "__OPAC_WWW_DIR__/.*/(modules|includes)"> > Order deny,allow > Deny from all > </DirectoryMatch> >@@ -113,6 +113,17 @@ > RewriteRule ^/isbn/([^\/]*)/?$ /search?q=isbn:$1 [PT] > RewriteRule ^/issn/([^\/]*)/?$ /search?q=issn:$1 [PT] > </IfModule> >+ >+ __PAZPAR2_TOGGLE_HTTPD_PRE__ >+ <Proxy *> >+ AddDefaultCharset off >+ Order deny,allow >+ Allow from all >+ </Proxy> >+ >+ ProxyRequests off >+ ProxyPass /pazpar2/search.pz2 http://__PAZPAR2_HOST__:__PAZPAR2_PORT__/search.pz2 >+ __PAZPAR2_TOGGLE_HTTPD_POST__ > </VirtualHost> > > ## Intranet >@@ -149,7 +160,7 @@ > </Directory> > > # Secure internal stuff >- <DirectoryMatch "__INTRANET_WWW_DIR__/.*/(modules|xslt|includes)"> >+ <DirectoryMatch "__INTRANET_WWW_DIR__/.*/(modules|includes)"> > Order deny,allow > Deny from all > </DirectoryMatch> >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 @@ >+<settings target="*"> >+ <!-- This file introduces default settings for pazpar2 --> >+ <!-- $Id: loc.xml,v 1.2 2007-07-10 13:43:07 adam Exp $ --> >+ >+ <!-- mapping for unqualified search --> >+ <set name="pz:cclmap:term" value="u=1016 t=l,r s=al"/> >+ >+ <!-- field-specific mappings --> >+ >+ <set name="pz:cclmap:au" value="u=1004 s=al"/> >+ <set name="pz:cclmap:ti" value="u=4 s=al"/> >+ <set name="pz:cclmap:su" value="u=21 s=al"/> >+ <set name="pz:cclmap:isbn" value="u=7"/> >+ <set name="pz:cclmap:issn" value="u=8"/> >+ <set name="pz:cclmap:date" value="u=30 r=r"/> >+ >+ <!-- Retrieval settings --> >+ >+ <set name="pz:elements" value="F"/> >+ >+</settings> >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 @@ > > <server> > <listen port="__PAZPAR2_PORT__"/> >- <settings src="__PAZPAR2_CONF_DIR__/koha-biblios.xml"/> >+ <settings src="__PAZPAR2_CONF_DIR__/generic-settings.xml"/> > > <relevance> > <icu_chain id="relevance" locale="el"> >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 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<xsl:stylesheet >+ version="1.0" >+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >+ xmlns:pz="http://www.indexdata.com/pazpar2/1.0" >+ xmlns:marc="http://www.loc.gov/MARC21/slim"> >+ >+ <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/> >+ >+ >+ <xsl:template match="/marc:record"> >+ <pz:record> >+ >+ <xsl:for-each select="marc:controlfield[@tag='001']"> >+ <pz:metadata type="id"> >+ <xsl:value-of select="."/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ <!-- --> >+ <xsl:for-each select="marc:datafield[@tag='020']"> >+ <xsl:if test="marc:subfield[@code='a'] = 'US'"> >+ <pz:metadata type="lccn"> >+ <xsl:value-of select="marc:subfield[@code='b']"/> >+ </pz:metadata> >+ </xsl:if> >+ </xsl:for-each> >+ >+ <xsl:for-each select="marc:datafield[@tag='010']"> >+ <pz:metadata type="isbn"> >+ <xsl:value-of select="marc:subfield[@code='a']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ <xsl:for-each select="marc:datafield[@tag='011']"> >+ <pz:metadata type="issn"> >+ <xsl:value-of select="marc:subfield[@code='a']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ >+ <xsl:for-each select="marc:datafield[@tag='200']"> >+ <pz:metadata type="work-title"> >+ <xsl:value-of select="marc:subfield[@code='a']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ >+ <!-- Date of Pulbication --> >+ <xsl:for-each select="marc:datafield[@tag='210']"> >+ <pz:metadata type="date"> >+ <xsl:value-of select="marc:subfield[@code='d']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ <!-- Usmarc 650 maps to unimarc 606 and marc21 653 maps to unimarc 610 --> >+ <xsl:for-each select="marc:datafield[@tag='606' or @tag='610']"> >+ <pz:metadata type="subject"> >+ <xsl:value-of select="marc:subfield[@code='a']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ <xsl:for-each select="marc:datafield[@tag >= 300 and @tag <= 345] >+ [@tag != '325']"> >+ <pz:metadata type="description"> >+ <xsl:value-of select="*/text()"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ >+ <!-- Author : primary, alternative and secondary responsibility (equivalent marc21 tags : 100, 700 --> >+ <xsl:for-each select="marc:datafield[@tag='700' or @tag='701' or @tag='702']"> >+ <pz:metadata type="work-author"> >+ <xsl:value-of select="marc:subfield[@code='a']"/> >+ <xsl:text>, </xsl:text> >+ <xsl:value-of select="marc:subfield[@code='b']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ <!-- Author : marc21 tag 720 maps to unimarc 730 >+ <xsl:for-each select="marc:datafield[@tag='730']"> >+ <pz:metadata type="author"> >+ <xsl:value-of select="marc:subfield[@code='a']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ --> >+ >+ <!-- --> >+ <xsl:for-each select="marc:datafield[@tag='856']"> >+ <pz:metadata type="url"> >+ <xsl:value-of select="marc:subfield[@code='u']"/> >+ </pz:metadata> >+ </xsl:for-each> >+ >+ </pz:record> >+ </xsl:template> >+ >+</xsl:stylesheet> >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index 4b0f364..0a4ce6d 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -253,6 +253,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','<li><a href=\"http://worldcat.org/search?q={TITLE}\" target=\"_blank\">Other Libraries (WorldCat)</a></li>\n<li><a href=\"http://www.scholar.google.com/scholar?q={TITLE}\" target=\"_blank\">Other Databases (Google Scholar)</a></li>\n<li><a href=\"http://www.bookfinder.com/search/?author={AUTHOR}&title={TITLE}&st=xl&ac=qr\" target=\"_blank\">Online Stores (Bookfinder.com)</a></li>\n<li><a href=\"http://openlibrary.org/search/?author=({AUTHOR})&title=({TITLE})\" target=\"_blank\">Open Library (openlibrary.org)</a></li>','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'), >@@ -415,8 +416,225 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('XISBN','0','','Use with FRBRizeEditions. If ON, Koha will use the OCLC xISBN web service in the Editions tab on the detail pages. See: http://www.worldcat.org/affiliate/webservices/xisbn/app.jsp','YesNo'), > ('XISBNDailyLimit','999','','The xISBN Web service is free for non-commercial use when usage does not exceed 1000 requests per day','Integer'), > ('XSLTDetailsDisplay','default','','Enable XSL stylesheet control over details page display on intranet','Free'), >+<<<<<<< HEAD > ('XSLTResultsDisplay','default','','Enable XSL stylesheet control over results page display on intranet','Free'), > ('yuipath','local','local|http://yui.yahooapis.com/2.5.1/build','Insert the path to YUI libraries, choose local if you use koha offline','Choice'), > ('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'), > ('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo') > ; >+======= >+('XSLTResultsDisplay','default','','Enable XSL stylesheet control over results page display on intranet','Free'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AdvancedSearchTypes','itemtypes','itemtypes|ccode','Select which set of fields comprise the Type limit in the advanced search','Choice'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowOnShelfHolds', '0', '', 'Allow hold requests to be placed on items that are not on loan', 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('AllowHoldsOnDamagedItems', '1', '', 'Allow hold requests to be placed on damaged items', 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES('OpacSuppression', '0', '', 'Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details', 'YesNo'); >+-- FIXME: add FrameworksLoaded, noOPACUserLogin? >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('SMSSendDriver','','','Sets which SMS::Send driver is used to send SMS messages.','free'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('OrderPdfFormat','pdfformat::layout3pages','Controls what script is used for printing (basketgroups)','','free'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('CurrencyFormat','US','US|FR','Determines the display format of currencies. eg: \'36000\' is displayed as \'360 000,00\' in \'FR\' or \'360,000.00\' in \'US\'.','Choice'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('AcqCreateItem','ordering','ordering|receiving|cataloguing','Define when the item is created : when ordering, when receiving, or in cataloguing module','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AllowRenewalLimitOverride', '0', 'if ON, allows renewal limits to be overridden on the circulation screen',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('OPACShowHoldQueueDetails','none','none|priority|holds|holds_priority','Show holds details in OPAC','Choice'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'UseBranchTransferLimits', '0', '', 'If ON, Koha will will use the rules defined in branch_transfer_limits to decide if an item transfer should be allowed.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AllowHoldPolicyOverride', '0', 'Allow staff to override hold policies when placing holds',NULL,'YesNo'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'BranchTransferLimitsType', 'ccode', 'itemtype|ccode', 'When using branch transfer limits, choose whether to limit by itemtype or collection code.', 'Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsClientCode', '0', 'Client Code for using Syndetics Solutions content','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsEnabled', '0', 'Turn on Syndetics Enhanced Content','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsCoverImages', '0', 'Display Cover Images from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsTOC', '0', 'Display Table of Content information from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsSummary', '0', 'Display Summary Information from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsEditions', '0', 'Display Editions from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsExcerpt', '0', 'Display Excerpts and first chapters on OPAC from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsReviews', '0', 'Display Reviews on OPAC from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsAuthorNotes', '0', 'Display Notes about the Author on OPAC from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsAwards', '0', 'Display Awards on OPAC from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsSeries', '0', 'Display Series information on OPAC from Syndetics','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SyndeticsCoverImageSize', 'MC', 'Choose the size of the Syndetics Cover Image to display on the OPAC detail page, MC is Medium, LC is Large','MC|LC','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('NovelistSelectEnabled',0,'Enable Novelist Select content. Requires Novelist Profile and Password',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('NovelistSelectProfile',NULL,'Novelist Select user Password',NULL,'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('NovelistSelectPassword',NULL,'Enable Novelist user Profile',NULL,'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('NovelistSelectView','tab','Where to display Novelist Select content','tab|above|below|right','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OPACAmazonCoverImages', '0', 'Display cover images on OPAC from Amazon Web Services','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('AmazonCoverImages', '0', 'Display Cover Images in Staff Client from Amazon Web Services','','YesNo'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'StaffSerialIssueDisplayCount', '3', '', 'Number of serial issues to display per subscription in the Staff client', 'Integer'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'OPACSerialIssueDisplayCount', '3', '', 'Number of serial issues to display per subscription in the OPAC', 'Integer'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OPACShowCheckoutName','0','Displays in the OPAC the name of patron who has checked out the material. WARNING: Most sites should leave this off. It is intended for corporate or special sites which need to track who has the item.','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('LibraryThingForLibrariesID','','See:http://librarything.com/forlibraries/','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('LibraryThingForLibrariesEnabled','0','Enable or Disable Library Thing for Libraries Features','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('LibraryThingForLibrariesTabbedView','0','Put LibraryThingForLibraries Content in Tabs.','','YesNo'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'AllowNotForLoanOverride', '0', '', 'If ON, Koha will allow the librarian to loan a not for loan item.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RenewalPeriodBase', 'date_due', 'Set whether the renewal date should be counted from the date_due or from the moment the Patron asks for renewal ','date_due|now','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('viewISBD','1','Allow display of ISBD view of bibiographic records','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('viewLabeledMARC','0','Allow display of labeled MARC view of bibiographic records','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('viewMARC','1','Allow display of MARC view of bibiographic records','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('FilterBeforeOverdueReport','0','Do not run overdue report until filter selected','','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type)VALUES('SpineLabelFormat', '<itemcallnumber><copynumber>', '30|10', 'This preference defines the format for the quick spine label printer. Just list the fields you would like to see in the order you would like to see them, surrounded by <>, for example <itemcallnumber>.', 'Textarea'); >+INSERT INTO systempreferences (variable,value,options,explanation,type)VALUES('SpineLabelAutoPrint', '0', '', 'If this setting is turned on, a print dialog will automatically pop up for the quick spine label printer.', 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OPACFineNoRenewals','100','Fine limit above which user cannot renew books via OPAC','','Integer'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OverdueNoticeBcc','','Email address to bcc outgoing overdue notices sent by email','','free'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'NewItemsDefaultLocation', '', '', 'If set, all new items will have a location of the given Location Code ( Authorized Value type LOC )', ''); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'InProcessingToShelvingCart', '0', '', 'If set, when any item with a location code of PROC is ''checked in'', it''s location code will be changed to CART.', 'YesNo'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'ReturnToShelvingCart', '0', '', 'If set, when any item is ''checked in'', it''s location code will be changed to CART.', 'YesNo'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'DisplayClearScreenButton', '0', '', 'If set to ON, a clear screen button will appear on the circulation page.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type)VALUES('HidePatronName', '0', '', 'If this is switched on, patron''s cardnumber will be shown instead of their name on the holds and catalog screens', 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACSearchForTitleIn','<li><a href="http://worldcat.org/search?q={TITLE}" target="_blank">Other Libraries (WorldCat)</a></li>\n<li><a href="http://www.scholar.google.com/scholar?q={TITLE}" target="_blank">Other Databases (Google Scholar)</a></li>\n<li><a href="http://www.bookfinder.com/search/?author={AUTHOR}&title={TITLE}&st=xl&ac=qr" target="_blank">Online Stores (Bookfinder.com)</a></li>\n<li><a href="http://openlibrary.org/search/?author=({AUTHOR})&title=({TITLE})" target="_blank">Open Library (openlibrary.org)</a></li>','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.','70|10','Textarea'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACMySummaryHTML','','Enter the HTML that will appear in a column on the \'my summary\' and \'my reading history\' tabs when a user is logged in to the OPAC. Enter {BIBLIONUMBER}, {TITLE}, {AUTHOR}, or {ISBN} in place of their respective variables in the HTML. Leave blank to disable.','70|10','Textarea'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACPatronDetails','1','If OFF the patron details tab in the OPAC is disabled.','','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACFinesTab','1','If OFF the patron fines tab in the OPAC is disabled.','','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type)VALUES('DisplayOPACiconsXSLT', '1', '', 'If ON, displays the format, audience, and material type icons in XSLT MARC21 results and detail pages in the OPAC.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AllowAllMessageDeletion','0','Allow any Library to delete any message','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('ShowPatronImageInWebBasedSelfCheck', '0', 'If ON, displays patron image when a patron uses web-based self-checkout', '', 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('EnableOpacSearchHistory', '1', 'Enable or disable opac search history', 'YesNo',''); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('RoutingListAddReserves','1','If ON the patrons on routing lists are automatically added to holds on the issue.','','YesNo'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ( 'OpacAddMastheadLibraryPulldown', '0', '', 'Adds a pulldown menu to select the library to search on the opac masthead.', 'YesNo' ); >+INSERT INTO systempreferences VALUES ('ImageLimit',5,'','Limit images stored in the database by the Patron Card image manager to this number.','Integer'); >+INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('SpineLabelShowPrintOnBibDetails', '0', '', 'If turned on, a "Print Label" link will appear for each item on the bib details page in the staff interface.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type)VALUES('AutoSelfCheckAllowed', '0', 'For corporate and special libraries which want web-based self-check available from any PC without the need for a manual staff login. Most libraries will want to leave this turned off. If on, requires self-check ID and password to be entered in AutoSelfCheckID and AutoSelfCheckPass sysprefs.', '', 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('AutoSelfCheckID','','Staff ID with circulation rights to be used for automatic web-based self-check. Only applies if AutoSelfCheckAllowed syspref is turned on.','','free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('AutoSelfCheckPass','','Password to be used for automatic web-based self-check. Only applies if AutoSelfCheckAllowed syspref is turned on.','','free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('soundon','0','Enable circulation sounds during checkin and checkout in the staff interface. Not supported by all web browsers yet.','','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('UseTablesortForCirc','0','If on, use the JQuery tablesort function on the list of current borrower checkouts on the circulation page. Note that the use of this function may slow down circ for patrons with may checkouts.','','YesNo'); >+INSERT INTO `systempreferences` ( `variable` , `value` , `options` , `explanation` , `type` ) VALUES ( 'PrintNoticesMaxLines', '0', '', 'If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.', 'Integer' ); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ILS-DI','0','Enables ILS-DI services at OPAC.','','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ILS-DI:AuthorizedIPs','','.','Restricts usage of ILS-DI to some IPs','Free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OverduesBlockCirc','noblock','When checking out an item should overdues block checkout, generate a confirmation dialogue, or allow checkout','noblock|confirmation|block','Choice'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('DisplayMultiPlaceHold','1','Display the ability to place multiple holds or not','','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('ShelfBrowserUsesLocation','1','Use the item location when finding items for the shelf browser.','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('ShelfBrowserUsesHomeBranch','1','Use the item home branch when finding items for the shelf browser.','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('ShelfBrowserUsesCcode','1','Use the item collection code when finding items for the shelf browser.','0','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowFineOverride','0','If on, staff will be able to issue books to patrons with fines greater than noissuescharge.','0','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllFinesNeedOverride','1','If on, staff will be asked to override every fine, even if it is below noissuescharge.','0','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AuthoritiesLog','0','If ON, log edit/create/delete actions on authorities.','0','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('TraceCompleteSubfields','0','Force subject tracings to only match complete subfields.','0','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('UseAuthoritiesForTracings','1','Use authority record numbers for subject tracings instead of heading strings.','0','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OPACAllowUserToChooseBranch', 1, 'Allow the user to choose the branch they want to pickup their hold from','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('displayFacetCount', '0', NULL, NULL, 'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('maxRecordsForFacets', '20', NULL, NULL, 'Integer'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('AllowPurchaseSuggestionBranchChoice', 0, 'Allow user to choose branch when making a purchase suggestion','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacFavicon','','Enter a complete URL to an image to replace the default Koha favicon on the OPAC','','free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('IntranetFavicon','','Enter a complete URL to an image to replace the default Koha favicon on the Staff client','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('TraceSubjectSubdivisions', '0', 'Create searches on all subdivisions for subject tracings.','1','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('UseICU', '0', 'Tell Koha if ICU indexing is in use for Zebra or not.','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('StaffAuthorisedValueImages','1','',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OPACDisplay856uAsImage','OFF','Display the URI in the 856u field as an image, the corresponding OPACXSLT option must be on','OFF|Details|Results|Both','Choice'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('Display856uAsImage','OFF','Display the URI in the 856u field as an image, the corresponding Staff Client XSLT option must be on','OFF|Details|Results|Both','Choice'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('AlternateHoldingsField','','The MARC field/subfield that contains alternate holdings information for bibs taht do not have items attached (e.g. 852abchi for libraries converting from MARC Magician).',NULL,'free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('AlternateHoldingsSeparator','','The string to use to separate subfields in alternate holdings displays.',NULL,'free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacHiddenItems','','This syspref allows to define custom rules for hiding specific items at opac. See docs/opac/OpacHiddenItems.txt for more informations.','','Textarea'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('numSearchRSSResults',50,'Specify the maximum number of results to display on a RSS page of results',NULL,'Integer'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacRenewalBranch','checkoutbranch','Choose how the branch for an OPAC renewal is recorded in statistics','itemhomebranch|patronhomebranch|checkoutbranch|null','Choice'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('UseTransportCostMatrix',0,"Use Transport Cost Matrix when filling holds",'','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('UNIMARCAuthorityField100', 'afrey50 ba0', NULL, NULL, 'Textarea'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0,'If ON Openlibrary book covers will be show',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('BorrowerUnwantedField','','Name the fields you don\'t need to store for a patron\'s account',NULL,'free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OpacKohaUrl','1',"Show 'Powered by Koha' text on OPAC footer.",NULL,NULL); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('EasyAnalyticalRecords','0','If on, display in the catalogue screens tools to easily setup analytical record relationships','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowRecentComments',0,'If ON a link to recent comments will appear in the OPAC masthead',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('CircAutoPrintQuickSlip', '1', 'Choose what should happen when an empty barcode field is submitted in circulation: Display a print quick slip window or Clear the screen.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('RentalsInNoissuesCharge', '1', 'Rental charges block checkouts (added to noissuescharge).',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('ManInvInNoissuesCharge', '1', 'MANUAL_INV charges block checkouts (added to noissuescharge).',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('NoticeCSS','','Notices CSS url.',NULL,'free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SlipCSS','','Slips CSS url.',NULL,'free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('TransferWhenCancelAllWaitingHolds','0','Transfer items when cancelling all waiting holds',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACLocalCoverImages','0','Display local cover images on OPAC search and details pages.','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('LocalCoverImages','0','Display local cover images on intranet details pages.','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowMultipleCovers','0','Allow multiple cover images to be attached to each bibliographic record.','1','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('BorrowerRenewalPeriodBase', 'now', 'Set whether the borrower renewal date should be counted from the dateexpiry or from the current date ','dateexpiry|now','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('AllowItemsOnHoldCheckout',0,'Do not generate RESERVE_WAITING and RESERVED warning when checking out items reserved to someone else. This allows self checkouts for those items.','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacExportOptions','bibtex|dc|marcxml|marc8|utf8|marcstd|mods|ris','Define export options available on OPAC detail page.','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AutoCreateAuthorities',0,'Automatically create authorities that do not exist when cataloging records.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('LinkerModule','Default','Chooses which linker module to use (see documentation).','Default|FirstMatch|LastMatch','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('LinkerOptions','','A pipe-separated list of options for the linker.','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('LinkerRelink',1,'If ON the authority linker will relink headings that have previously been linked every time it runs.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('LinkerKeepStale',0,'If ON the authority linker will keep existing authority links for headings where it is unable to find a match.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('CatalogModuleRelink',0,'If OFF the linker will never replace the authids that are set in the cataloging module.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('ExpireReservesMaxPickUpDelay', '0', '', 'Enabling this allows holds to expire automatically if they have not been picked by within the time period specified in ReservesMaxPickUpDelay', 'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('ExpireReservesMaxPickUpDelayCharge', '0', NULL , 'If ExpireReservesMaxPickUpDelay is enabled, and this field has a non-zero value, than a borrower whose waiting hold has expired will be charged this amount.', 'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('CalendarFirstDayOfWeek','Sunday','Select the first day of week to use in the calendar.','Sunday|Monday','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RoutingListNote','To change this note edit <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=RoutingListNote#jumped">RoutlingListNote</a> system preference.','Define a note to be shown on all routing lists','70|10','Textarea'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('AllowPKIAuth','None','Use the field from a client-side SSL certificate to look a user in the Koha database','None|Common Name|emailAddress','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OAI-PMH:AutoUpdateSets','0','Automatically update OAI sets when a bibliographic record is created or updated','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacAllowPublicListCreation',1,'If set, allows opac users to create public lists',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacAllowSharingPrivateLists',0,'If set, allows opac users to share private lists with other patrons',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_js','','Url for Babeltheque javascript (e.g. http://www.babeltheque.com/bw_XX.js)','','Free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_update', '', 'Url for Babeltheque update (E.G. http://www.babeltheque.com/.../file.csv.bz2)', '', 'Free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SocialNetworks','0','Enable/Disable social networks links in opac detail pages','','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('SubscriptionDuplicateDroppedInput','','','List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)','Free'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('AutoResumeSuspendedHolds', '1', NULL , 'Allow suspended holds to be automatically resumed by a set date.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacStarRatings','all',NULL,'disable|all|details','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacBrowseResults','1','Disable/enable browsing and paging search results from the OPAC detail page.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SvcMaxReportRows','10','Maximum number of rows to return via the report web service.',NULL,'Integer'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('decreaseLoanHighHolds', NULL, '', 'Decreases the loan period for items with number of holds above the threshold specified in decreaseLoanHighHoldsValue', 'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('decreaseLoanHighHoldsValue', NULL, '', 'Specifies a threshold for the minimum number of holds needed to trigger a reduction in loan duration (used with decreaseLoanHighHolds)', 'Integer'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('decreaseLoanHighHoldsDuration', NULL, '', 'Specifies a number of days that a loan is reduced to when used in conjunction with decreaseLoanHighHolds', 'Integer'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('IssueLostItem', 'alert', 'alert|confirm|nothing', 'Defines what should be done when an attempt is made to issue an item that has been marked as lost.', 'Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SuspendHoldsIntranet', '1', NULL , 'Allow holds to be suspended from the intranet.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SuspendHoldsOpac', '1', NULL , 'Allow holds to be suspended from the OPAC.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('DefaultLanguageField008','','Fill in the default language for field 008 Range 35-37 (e.g. eng, nor, ger, see <a href="http://www.loc.gov/marc/languages/language_code.html">MARC Code List for Languages</a>)','','Free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OPACShowBarcode','0','Show items barcode in holding tab','','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('OPACShowUnusedAuthorities','1','','Show authorities that are not being used in the OPAC.','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,type) VALUES('EnableBorrowerFiles','0','If enabled, allows librarians to upload and attach arbitrary files to a borrower record.','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UpdateTotalIssuesOnCirc','0','Whether to update the totalissues field in the biblio on each circ.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('IntranetSlipPrinterJS','','Use this JavaScript for printing slips. Define at least function printThenClose(). For use e.g. with Firefox PlugIn jsPrintSetup, see http://jsprintsetup.mozdev.org/','','Free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSuppressionByIPRange','','Restrict the suppression to IP adresses outside of the IP range','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('PrefillItem','0','When a new item is added, should it be prefilled with last created item values?','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('SubfieldsToUseWhenPrefill','','Define a list of subfields to use when prefilling items (separated by space)','','Free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AgeRestrictionMarker','','Markers for age restriction indication, e.g. FSK|PEGI|Age|',NULL,'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AgeRestrictionOverride',0,'Allow staff to check out an item with age restriction.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('IncludeSeeFromInSearches','0','','Include see-from references in searches.','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OPACMobileUserCSS','','Include the following CSS for the mobile view on all pages in the OPAC:',NULL,'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacMainUserBlockMobile','','Show the following HTML in its own column on the main page of the OPAC (mobile version):',NULL,'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowLibrariesPulldownMobile','1','Show the libraries pulldown on the mobile version of the OPAC.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowFiltersPulldownMobile','1','Show the search filters pulldown on the mobile version of the OPAC.',NULL,'YesNo'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('AuthDisplayHierarchy','0','Display authority hierarchies','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,type) VALUES('OPACdidyoumean',NULL,'Did you mean? configuration for the OPAC. Do not change, as this is controlled by /cgi-bin/koha/admin/didyoumean.pl.','Free'); >+INSERT INTO systempreferences (variable,value,explanation,type) VALUES('INTRAdidyoumean',NULL,'Did you mean? configuration for the Intranet. Do not change, as this is controlled by /cgi-bin/koha/admin/didyoumean.pl.','Free'); >+INSERT INTO systempreferences (variable, value, options, explanation, type) VALUES ('BlockReturnOfWithdrawnItems', '1', '0', 'If enabled, items that are marked as withdrawn cannot be returned.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HoldsToPullStartDate','2','Set the default start date for the Holds to pull list to this many days ago',NULL,'Integer'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('alphabet','A B C D E F G H I J K L M N O P Q R S T U V W X Y Z','Alphabet than can be expanded into browse links, e.g. on Home > Patrons',NULL,'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RefundLostItemFeeOnReturn', '1', 'If enabled, the lost item fee charged to a borrower will be refunded when the lost item is returned.', NULL, 'YesNo'); >+INSERT INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES >+('PatronSelfRegistration', '0', NULL, 'If enabled, patrons will be able to register themselves via the OPAC.', 'YesNo'), >+('PatronSelfRegistrationVerifyByEmail', '0', NULL, 'If enabled, any patron attempting to register themselves via the OPAC will be required to verify themselves via email to activate his or her account.', 'YesNo'), >+('PatronSelfRegistrationDefaultCategory', '', '', 'A patron registered via the OPAC will receive a borrower category code set in this system preference.', 'free'), >+('PatronSelfRegistrationExpireTemporaryAccountsDelay', '0', NULL, 'If PatronSelfRegistrationDefaultCategory is enabled, this system preference controls how long a patron can have a temporary status before the account is deleted automatically. It is an integer value representing a number of days to wait before deleting a temporary patron account. Setting it to 0 disables the deleting of temporary accounts.', 'Integer'), >+('PatronSelfRegistrationBorrowerMandatoryField', 'surname|firstname', NULL , 'Choose the mandatory fields for a patron''s account, when registering via the OPAC.', 'free'), >+('PatronSelfRegistrationBorrowerUnwantedField', '', NULL , 'Name the fields you don''t want to display when registering a new patron via the OPAC.', 'free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SeparateHoldings', '0', 'Separate current branch holdings from other holdings', NULL, 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SeparateHoldingsBranch', 'homebranch', 'Branch used to separate holdings', 'homebranch|holdingbranch', 'Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSeparateHoldings', '0', 'Separate current branch holdings from other holdings (OPAC)', NULL, 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacSeparateHoldingsBranch', 'homebranch', 'Branch used to separate holdings (OPAC)', 'homebranch|holdingbranch', 'Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RenewalSendNotice','0', NULL, '', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaEnabled','not','Show a tab with a HTML5 media player for files catalogued in field 856','not|opac|staff|both','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HTML5MediaExtensions','webm|ogg|ogv|oga|vtt','Media file extensions','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('AllowHoldsOnPatronsPossessions', '1', 'Allow holds on records that patron have items of it',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('NotesBlacklist','','List of notes fields that should not appear in the title notes/description separator of details',NULL,'free'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('SCOUserCSS', '', NULL, 'Add CSS to be included in the SCO module in an embedded <style> tag.', 'free'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('SCOUserJS', '', NULL, 'Define custom javascript for inclusion in the SCO module', 'free'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('IDreamBooksReviews','0','Display book review snippets from IDreamBooks.com','','YesNo'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('IDreamBooksReadometer','0','Display Readometer from IDreamBooks.com','','YesNo'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('IDreamBooksResults','0','Display IDreamBooks.com rating in search results','','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('OPACNumbersPreferPhrase','0', NULL, 'Control the use of phr operator in callnumber and standard number OPAC searches', 'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('IntranetNumbersPreferPhrase','0', NULL, 'Control the use of phr operator in callnumber and standard number staff client searches', 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UNIMARCField100Language', 'fre','UNIMARC field 100 default language',NULL,'short'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('Persona',0,'Use Mozilla Persona for login','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacItemLocation','callnum','Show the shelving location of items in the opac','callnum|ccode|location','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('TrackClicks','0','Track links clicked',NULL,'Integer'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('PatronSelfRegistrationAdditionalInstructions','','A free text field to display additional instructions to newly self registered patrons.','','free'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UseQueryParser', '0', 'If enabled, try to use QueryParser for queries.', NULL, 'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('FinesIncludeGracePeriod','1','If enabled, fines calculations will include the grace period.',NULL,'YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('UNIMARCAuthorsFacetsSeparator',', ', 'UNIMARC authors facets separator', NULL, 'short'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UseKohaPlugins','0','Enable or disable the ability to use Koha Plugins.','','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('TimeFormat','24hr','12hr|24hr','Defines the global time format for visual output.','Choice'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('DisplayIconsXSLT', '1', '', 'If ON, displays the format, audience, and material type icons in XSLT MARC21 results and detail pages.', 'YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('HighlightOwnItemsOnOPAC','0','','If on, and a patron is logged into the OPAC, items from his or her home library will be emphasized and shown first in search results and item details.','YesNo'); >+INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('HighlightOwnItemsOnOPACWhich','PatronBranch','PatronBranch|OpacURLBranch','Decides which branch''s items to emphasize. If PatronBranch, emphasize the logged in user''s library''s items. If OpacURLBranch, highlight the items of the Apache var BRANCHCODE defined in Koha''s Apache configuration file.','Choice'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UniqueItemFields', 'barcode', 'Space-separated list of fields that should be unique (used in acquisition module for item creation). Fields must be valid SQL column names of items table', '', 'Free'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('UseCourseReserves', '0', 'Enable the course reserves feature.', NULL, 'YesNo'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacHoldNotes',0,'Show hold notes on OPAC','','YesNo'); >+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('CalculateFinesOnReturn','1','Switch to control if overdue fines are calculated on return or not', '', 'YesNo'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('OPACSearchExternalTargets','0','Whether to search external targets in the OPAC','','YesNo'); >+>>>>>>> Bug 10486 - Allow external Z39.50 targets to be searched from the OPAC (2/2) >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index a37ea02..0bbeb66 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -7155,6 +7155,39 @@ if ( CheckVersion($DBversion) ) { > SetVersion($DBversion); > } > >+$DBversion = "3.13.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=utf >+ } ); >+ 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 308e3a0..af8b18f 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; >@@ -939,16 +953,6 @@ div.sysprefs div.hint { > margin : .7em; > } > >-tr.highlight td { >- background-color : #F6F6F6; >- border-color : #BCBCBC; >-} >- >-tr.highlight th[scope=row] { >- background-color : #DDDDDD; >- border-color : #BCBCBC; >-} >- > #circ_circulation_issue label { > font-size: 105%; > 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 @@ > <li><a href="/cgi-bin/koha/admin/classsources.pl">Classification sources</a></li> > <li><a href="/cgi-bin/koha/admin/matching-rules.pl">Record matching rules</a></li> > <li><a href="/cgi-bin/koha/admin/oai_sets.pl">OAI sets configuration</a></li> >+ <li><a href="/cgi-bin/koha/admin/external_targets.pl">External search targets</a></li> > </ul> > > <h5>Acquisition parameters</h5> >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 a5dbe44..f705181 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 @@ > <dt><a href="/cgi-bin/koha/admin/searchengine/solr/indexes.pl">Search engine configuration</a></dt> > <dd>Manage indexes, facets, and their mappings to MARC fields and subfields.</dd> > [% END %] >+ <dt><a href="/cgi-bin/koha/admin/external_targets.pl">External search targets</a></dt> >+ <dd>Define external search targets that can be searched from the OPAC.</dd> > </dl> > > <h3>Acquisition parameters</h3> >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' %] >+<title>Koha › Administration › External targets</title> >+[% ELSIF op == 'add' %] >+<title>Koha › Administration › External targets › Create an external target</title> >+[% ELSIF op == 'edit' %] >+<title>Koha › Administration › External targets › Editing '[% target.name %]'</title> >+[% END %] >+[% INCLUDE 'doc-head-close.inc' %] >+<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> >+[% INCLUDE 'datatables-strings.inc' %] >+<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> >+<script type="text/javascript"> >+//<![CDATA[ >+ $(document).ready(function() { >+ [% IF ( targets.size ) %] >+ var dTable = $("#targets").dataTable( $.extend( true, {}, dataTablesDefaults, { >+ aoColumnDefs: [ >+ { aTargets: [ 1,2,3,4,5 ], bSortable: false, bSearchable: false }, >+ ], >+ asStripeClasses: [ '', 'highlight' ], >+ bPaginate: false, >+ } ) ); >+ >+ [% IF saved_id %] >+ $( '#targets tr[data-targetid=[% saved_id %]]' ).addClass( 'updated' ); >+ [% END %] >+ >+ $( '#targets .delete' ).click( function() { >+ return confirm( _( 'Are you sure you wish to delete this target?' ) ); >+ } ); >+ [% END %] >+ }); >+//]]> >+</script> >+ >+</head> >+<body id="admin_z3950servers" class="admin"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-search.inc' %] >+ >+[% IF op == 'show' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> › External targets</div> >+ >+[% ELSIF op == 'add' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> › <a href="/cgi-bin/koha/admin/external_targets.pl">External targets</a> › Create an external target</div> >+ >+[% ELSIF op == 'edit' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> › <a href="/cgi-bin/koha/admin/external_targets.pl">External targets</a> › Editing '[% target.name %]'</div> >+ >+[% END %] >+ >+<div id="doc3" class="yui-t2"> >+<div id="bd"> >+ >+<div id="yui-main"><div class="yui-b"> >+ >+[% IF op == 'show' %] >+ >+[% IF deleted_name %] >+<div class="alert"> >+ <p>Deleted target '[% deleted_name %]'</p> >+</div> >+[% END %] >+ >+<div id="toolbar" class="btn-toolbar"> >+ <a id="newtarget" class="btn btn-small" href="/cgi-bin/koha/admin/external_targets.pl?op=add"><i class="icon-plus"></i> New external target</a> >+</div> >+ >+<p>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.</p> >+ >+[% IF targets.size %] >+<table id="targets"> >+ <thead><tr><th>Name</th><th>Connection</th><th>Login</th><th>Syntax</th><th>Encoding</th><th> </th><th> </th></tr></thead> >+ <tbody> >+ [% FOREACH target = targets %] >+ <tr data-targetid="[% target.target_id %]"> >+ <td>[% target.name %]</td> >+ <td>[% target.host %]:[% target.port %]/[% target.db %]</td> >+ <td>[% IF target.userid %][% target.userid %] / [% IF target.password %]********[% ELSE %]<span class="hint">none</span>[% END %][% ELSE %]<span class="hint">none</span>[% END %]</td> >+ <td>[% target.syntax %]</td> >+ <td> >+ [% IF target.encoding == 'marc8' %] >+ MARC-8 >+ [% ELSIF target.encoding == 'utf8' %] >+ UTF-8 >+ [% END %] >+ </td> >+ <td><a href="/cgi-bin/koha/admin/external_targets.pl?op=edit&target_id=[% target.target_id %]">Edit</a></td> >+ <td><a class="delete" href="/cgi-bin/koha/admin/external_targets.pl?op=delete&target_id=[% target.target_id %]">Delete</a></td> >+ </tr> >+ [% END %] >+ </tbody> >+</table> >+[% ELSE %] >+<p>No external targets have been defined yet.</p> >+[% END %] >+ >+[% ELSIF op == 'add' || op == 'edit' %] >+ >+<form action="/cgi-bin/koha/admin/external_targets.pl" method="POST"> >+ [% IF op == 'add' %] >+ <h1>Create an external target</h1> >+ [% ELSIF op == 'edit' %] >+ <h1>Editing '[% target.name %]'</h1> >+ [% END %] >+ >+ <input type="hidden" name="op" value="save"> >+ <input type="hidden" name="target_id" value="[% target.target_id %]"> >+ >+ <fieldset class="rows"> >+ <ol> >+ <li><label for="name">Name:</label> <input type="text" id="name" name="name" value="[% target.name %]" required></li> >+ <li><label for="host">Host:</label> <input type="text" id="host" name="host" value="[% target.host %]" required></li> >+ <li><label for="port">Port:</label> <input type="num" id="port" name="port" value="[% target.port %]" required></li> >+ <li><label for="db">Database:</label> <input type="text" id="db" name="db" value="[% target.db %]" required></li> >+ <li><label for="userid">User:</label> <input type="text" id="userid" name="userid" value="[% target.userid %]"></li> >+ <li><label for="password">Password:</label> <input type="password" id="password" name="password" value="[% target.password %]" autocomplete="off"></li> >+ <li> >+ <label for="syntax">Syntax:</label> >+ <select id="syntax" name="syntax"> >+ [% FOREACH syntax = syntaxes %] >+ [% IF syntax == target.syntax %] >+ <option selected>[% syntax %] >+ [% ELSE %] >+ <option>[% syntax %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ <li> >+ <label for="encoding">Encoding:</label> >+ <select id="encoding" name="encoding"> >+ [% FOREACH encoding = encodings %] >+ [% IF encoding.key == target.encoding %] >+ <option value="[% encoding.key %]" selected>[% encoding.value %] >+ [% ELSE %] >+ <option value="[% encoding.key %]">[% encoding.value %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ <li> >+ <label>Restricted libraries:</label> >+ <fieldset> >+ <legend>Not available to patrons from:</legend> >+ <p>Only targets with no restrictions will be shown to anonymous (not logged in) users.</p> >+ <ol> >+ [% FOREACH branch = branches %] >+ <li> >+ <label for="branch-[% branch.branchcode %]">[% branch.branchname %]</label> >+ [% IF branch.selected %] >+ <input type="checkbox" id="branch-[% branch.branchcode %]" name="branch" value="[% branch.branchcode %]" checked /> >+ [% ELSE %] >+ <input type="checkbox" id="branch-[% branch.branchcode %]" name="branch" value="[% branch.branchcode %]" /> >+ [% END %] >+ </li> >+ [% END %] >+ </ol> >+ </fieldset> >+ </li> >+ </ol> >+ </fieldset> >+ >+ <fieldset class="action"><input type="submit" value="Save"></fieldset> >+</form> >+ >+[% END %] >+ >+</div></div> >+<div class="yui-b"> >+[% INCLUDE 'admin-menu.inc' %] >+</div> >+ >+</div> >+[% 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 = $('<iframe id="foo" style="z-index: ' + (opts.zIndex + 1) + ';border: none; margin: 0; padding: 0; position: absolute; width: 100%; height: 100%; top: 0; left: 0; filter: mask();"/>'), >+ ie6 = ($.browser.msie && $.browser.version < 7); >+ >+ if (opts.showOverlay) { >+ //check if there's an existing overlay, if so, make subequent ones clear >+ var $currentOverlays = $(".js_lb_overlay:visible"); >+ if ($currentOverlays.length > 0){ >+ $overlay = $('<div class="lb_overlay_clear js_lb_overlay"/>'); >+ } else { >+ $overlay = $('<div class="' + opts.classPrefix + '_overlay js_lb_overlay"/>'); >+ } >+ } >+ >+ /*---------------------------------------------------- >+ DOM Building >+ ---------------------------------------------------- */ >+ if (ie6) { >+ var src = /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'; >+ $iframe.attr('src', src); >+ $('body').append($iframe); >+ } // iframe shim for ie6, to hide select elements >+ $('body').append($self.hide()).append($overlay); >+ >+ >+ /*---------------------------------------------------- >+ Overlay CSS stuffs >+ ---------------------------------------------------- */ >+ >+ // set css of the overlay >+ if (opts.showOverlay) { >+ setOverlayHeight(); // pulled this into a function because it is called on window resize. >+ $overlay.css({ position: 'absolute', width: '100%', top: 0, left: 0, right: 0, bottom: 0, zIndex: (opts.zIndex + 2), display: 'none' }); >+ if (!$overlay.hasClass('lb_overlay_clear')){ >+ $overlay.css(opts.overlayCSS); >+ } >+ } >+ >+ /*---------------------------------------------------- >+ Animate it in. >+ ---------------------------------------------------- */ >+ // >+ if (opts.showOverlay) { >+ $overlay.fadeIn(opts.overlaySpeed, function() { >+ setSelfPosition(); >+ $self[opts.appearEffect](opts.lightboxSpeed, function() { setOverlayHeight(); setSelfPosition(); opts.onLoad()}); >+ }); >+ } else { >+ setSelfPosition(); >+ $self[opts.appearEffect](opts.lightboxSpeed, function() { opts.onLoad()}); >+ } >+ >+ /*---------------------------------------------------- >+ Hide parent if parent specified (parentLightbox should be jquery reference to any parent lightbox) >+ ---------------------------------------------------- */ >+ if (opts.parentLightbox) { >+ opts.parentLightbox.fadeOut(200); >+ } >+ >+ >+ /*---------------------------------------------------- >+ Bind Events >+ ---------------------------------------------------- */ >+ >+ $(window).resize(setOverlayHeight) >+ .resize(setSelfPosition) >+ .scroll(setSelfPosition); >+ >+ $(window).bind('keyup.lightbox_me', observeKeyPress); >+ >+ if (opts.closeClick) { >+ $overlay.click(function(e) { closeLightbox(); e.preventDefault; }); >+ } >+ $self.delegate(opts.closeSelector, "click", function(e) { >+ closeLightbox(); e.preventDefault(); >+ }); >+ $self.bind('close', closeLightbox); >+ $self.bind('reposition', setSelfPosition); >+ >+ >+ >+ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- >+ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ >+ >+ >+ /*---------------------------------------------------- >+ Private Functions >+ ---------------------------------------------------- */ >+ >+ /* Remove or hide all elements */ >+ function closeLightbox() { >+ var s = $self[0].style; >+ if (opts.destroyOnClose) { >+ $self.add($overlay).remove(); >+ } else { >+ $self.add($overlay).hide(); >+ } >+ >+ //show the hidden parent lightbox >+ if (opts.parentLightbox) { >+ opts.parentLightbox.fadeIn(200); >+ } >+ >+ $iframe.remove(); >+ >+ // clean up events. >+ $self.undelegate(opts.closeSelector, "click"); >+ >+ $(window).unbind('reposition', setOverlayHeight); >+ $(window).unbind('reposition', setSelfPosition); >+ $(window).unbind('scroll', setSelfPosition); >+ $(window).unbind('keyup.lightbox_me'); >+ if (ie6) >+ s.removeExpression('top'); >+ opts.onClose(); >+ } >+ >+ >+ /* Function to bind to the window to observe the escape/enter key press */ >+ function observeKeyPress(e) { >+ if((e.keyCode == 27 || (e.DOM_VK_ESCAPE == 27 && e.which==0)) && opts.closeEsc) closeLightbox(); >+ } >+ >+ >+ /* Set the height of the overlay >+ : if the document height is taller than the window, then set the overlay height to the document height. >+ : otherwise, just set overlay height: 100% >+ */ >+ function setOverlayHeight() { >+ if ($(window).height() < $(document).height()) { >+ $overlay.css({height: $(document).height() + 'px'}); >+ $iframe.css({height: $(document).height() + 'px'}); >+ } else { >+ $overlay.css({height: '100%'}); >+ if (ie6) { >+ $('html,body').css('height','100%'); >+ $iframe.css('height', '100%'); >+ } // ie6 hack for height: 100%; TODO: handle this in IE7 >+ } >+ } >+ >+ >+ /* Set the position of the modal'd window ($self) >+ : if $self is taller than the window, then make it absolutely positioned >+ : otherwise fixed >+ */ >+ function setSelfPosition() { >+ var s = $self[0].style; >+ >+ // reset CSS so width is re-calculated for margin-left CSS >+ $self.css({left: '50%', marginLeft: ($self.outerWidth() / 2) * -1, zIndex: (opts.zIndex + 3) }); >+ >+ >+ /* we have to get a little fancy when dealing with height, because lightbox_me >+ is just so fancy. >+ */ >+ >+ // if the height of $self is bigger than the window and self isn't already position absolute >+ if (($self.height() + 80 >= $(window).height()) && ($self.css('position') != 'absolute' || ie6)) { >+ >+ // we are going to make it positioned where the user can see it, but they can still scroll >+ // so the top offset is based on the user's scroll position. >+ var topOffset = $(document).scrollTop() + 40; >+ $self.css({position: 'absolute', top: topOffset + 'px', marginTop: 0}) >+ if (ie6) { >+ s.removeExpression('top'); >+ } >+ } else if ($self.height()+ 80 < $(window).height()) { >+ //if the height is less than the window height, then we're gonna make this thing position: fixed. >+ // in ie6 we're gonna fake it. >+ if (ie6) { >+ s.position = 'absolute'; >+ if (opts.centered) { >+ s.setExpression('top', '(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"') >+ s.marginTop = 0; >+ } else { >+ var top = (opts.modalCSS && opts.modalCSS.top) ? parseInt(opts.modalCSS.top) : 0; >+ s.setExpression('top', '((blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"') >+ } >+ } else { >+ if (opts.centered) { >+ $self.css({ position: 'fixed', top: '50%', marginTop: ($self.outerHeight() / 2) * -1}) >+ } else { >+ $self.css({ position: 'fixed'}).css(opts.modalCSS); >+ } >+ >+ } >+ } >+ } >+ >+ }); >+ >+ >+ >+ }; >+ >+ $.fn.lightbox_me.defaults = { >+ >+ // animation >+ appearEffect: "fadeIn", >+ appearEase: "", >+ overlaySpeed: 250, >+ lightboxSpeed: 300, >+ >+ // close >+ closeSelector: ".close", >+ closeClick: true, >+ closeEsc: true, >+ >+ // behavior >+ destroyOnClose: false, >+ showOverlay: true, >+ parentLightbox: false, >+ >+ // callbacks >+ onLoad: function() {}, >+ onClose: function() {}, >+ >+ // style >+ classPrefix: 'lb', >+ zIndex: 999, >+ centered: false, >+ modalCSS: {top: '40px'}, >+ overlayCSS: {background: 'black', opacity: .3} >+ } >+})(jQuery); >\ No newline at end of file >diff --git a/koha-tmpl/opac-tmpl/lib/pz2.js b/koha-tmpl/opac-tmpl/lib/pz2.js >new file mode 100644 >index 0000000..9d693b2 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/lib/pz2.js >@@ -0,0 +1,1110 @@ >+/* >+ * $Id: 3a9980787bb5d0fe966140b243a4a5eb6768913e $ >+** pz2.js - pazpar2's javascript client library. >+*/ >+ >+//since explorer is flawed >+if (!window['Node']) { >+ window.Node = new Object(); >+ Node.ELEMENT_NODE = 1; >+ Node.ATTRIBUTE_NODE = 2; >+ Node.TEXT_NODE = 3; >+ Node.CDATA_SECTION_NODE = 4; >+ Node.ENTITY_REFERENCE_NODE = 5; >+ Node.ENTITY_NODE = 6; >+ Node.PROCESSING_INSTRUCTION_NODE = 7; >+ Node.COMMENT_NODE = 8; >+ Node.DOCUMENT_NODE = 9; >+ Node.DOCUMENT_TYPE_NODE = 10; >+ Node.DOCUMENT_FRAGMENT_NODE = 11; >+ Node.NOTATION_NODE = 12; >+} >+ >+// prevent execution of more than once >+if(typeof window.pz2 == "undefined") { >+window.undefined = window.undefined; >+ >+var pz2 = function ( paramArray ) >+{ >+ >+ // at least one callback required >+ if ( !paramArray ) >+ throw new Error("Pz2.js: Array with parameters has to be supplied."); >+ >+ //supported pazpar2's protocol version >+ this.suppProtoVer = '1'; >+ if (typeof paramArray.pazpar2path != "undefined") >+ this.pz2String = paramArray.pazpar2path; >+ else >+ this.pz2String = "/pazpar2/search.pz2"; >+ this.useSessions = true; >+ >+ this.stylesheet = paramArray.detailstylesheet || null; >+ //load stylesheet if required in async mode >+ if( this.stylesheet ) { >+ var context = this; >+ var request = new pzHttpRequest( this.stylesheet ); >+ request.get( {}, function ( doc ) { context.xslDoc = doc; } ); >+ } >+ >+ this.errorHandler = paramArray.errorhandler || null; >+ this.showResponseType = paramArray.showResponseType || "xml"; >+ >+ // function callbacks >+ this.initCallback = paramArray.oninit || null; >+ this.statCallback = paramArray.onstat || null; >+ this.showCallback = paramArray.onshow || null; >+ this.termlistCallback = paramArray.onterm || null; >+ this.recordCallback = paramArray.onrecord || null; >+ this.bytargetCallback = paramArray.onbytarget || null; >+ this.resetCallback = paramArray.onreset || null; >+ >+ // termlist keys >+ this.termKeys = paramArray.termlist || "subject"; >+ >+ // some configurational stuff >+ this.keepAlive = 50000; >+ >+ if ( paramArray.keepAlive < this.keepAlive ) >+ this.keepAlive = paramArray.keepAlive; >+ >+ this.sessionID = paramArray.sessionId || null; >+ this.serviceId = paramArray.serviceId || null; >+ this.initStatusOK = false; >+ this.pingStatusOK = false; >+ this.searchStatusOK = false; >+ >+ // for sorting >+ this.currentSort = "relevance"; >+ >+ // where are we? >+ this.currentStart = 0; >+ // currentNum can be overwritten in show >+ this.currentNum = 20; >+ >+ // last full record retrieved >+ this.currRecID = null; >+ >+ // current query >+ this.currQuery = null; >+ >+ //current raw record offset >+ this.currRecOffset = null; >+ >+ //timers >+ this.pingTimer = null; >+ this.statTime = paramArray.stattime || 1000; >+ this.statTimer = null; >+ this.termTime = paramArray.termtime || 1000; >+ this.termTimer = null; >+ this.showTime = paramArray.showtime || 1000; >+ this.showTimer = null; >+ this.showFastCount = 4; >+ this.bytargetTime = paramArray.bytargettime || 1000; >+ this.bytargetTimer = null; >+ this.recordTime = paramArray.recordtime || 500; >+ this.recordTimer = null; >+ >+ // counters for each command and applied delay >+ this.dumpFactor = 500; >+ this.showCounter = 0; >+ this.termCounter = 0; >+ this.statCounter = 0; >+ this.bytargetCounter = 0; >+ this.recordCounter = 0; >+ >+ // active clients, updated by stat and show >+ // might be an issue since bytarget will poll accordingly >+ this.activeClients = 1; >+ >+ // if in proxy mode no need to init >+ if (paramArray.usesessions != undefined) { >+ this.useSessions = paramArray.usesessions; >+ this.initStatusOK = true; >+ } >+ // else, auto init session or wait for a user init? >+ if (this.useSessions && paramArray.autoInit !== false) { >+ this.init(this.sessionID, this.serviceId); >+ } >+ // Version parameter >+ this.version = paramArray.version || null; >+}; >+ >+pz2.prototype = >+{ >+ //error handler for async error throws >+ throwError: function (errMsg, errCode) >+ { >+ var err = new Error(errMsg); >+ if (errCode) err.code = errCode; >+ >+ if (this.errorHandler) { >+ this.errorHandler(err); >+ } >+ else { >+ throw err; >+ } >+ }, >+ >+ // stop activity by clearing tiemouts >+ stop: function () >+ { >+ clearTimeout(this.statTimer); >+ clearTimeout(this.showTimer); >+ clearTimeout(this.termTimer); >+ clearTimeout(this.bytargetTimer); >+ }, >+ >+ // reset status variables >+ reset: function () >+ { >+ if ( this.useSessions ) { >+ this.sessionID = null; >+ this.initStatusOK = false; >+ this.pingStatusOK = false; >+ clearTimeout(this.pingTimer); >+ } >+ this.searchStatusOK = false; >+ this.stop(); >+ >+ if ( this.resetCallback ) >+ this.resetCallback(); >+ }, >+ >+ init: function (sessionId, serviceId) >+ { >+ this.reset(); >+ >+ // session id as a param >+ if (sessionId && this.useSessions ) { >+ this.initStatusOK = true; >+ this.sessionID = sessionId; >+ this.ping(); >+ // old school direct pazpar2 init >+ } else if (this.useSessions) { >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ var opts = {'command' : 'init'}; >+ if (serviceId) opts.service = serviceId; >+ request.safeGet( >+ opts, >+ function(data) { >+ if ( data.getElementsByTagName("status")[0] >+ .childNodes[0].nodeValue == "OK" ) { >+ if ( data.getElementsByTagName("protocol")[0] >+ .childNodes[0].nodeValue >+ != context.suppProtoVer ) >+ throw new Error( >+ "Server's protocol not supported by the client" >+ ); >+ context.initStatusOK = true; >+ context.sessionID = >+ data.getElementsByTagName("session")[0] >+ .childNodes[0].nodeValue; >+ if (data.getElementsByTagName("keepAlive").length > 0) { >+ context.keepAlive = data.getElementsByTagName("keepAlive")[0].childNodes[0].nodeValue; >+ } >+ context.pingTimer = >+ setTimeout( >+ function () { >+ context.ping(); >+ }, >+ context.keepAlive >+ ); >+ if ( context.initCallback ) >+ context.initCallback(); >+ } >+ else >+ context.throwError('Init failed. Malformed WS resonse.', >+ 110); >+ } >+ ); >+ // when through proxy no need to init >+ } else { >+ this.initStatusOK = true; >+ } >+ }, >+ // no need to ping explicitly >+ ping: function () >+ { >+ // pinging only makes sense when using pazpar2 directly >+ if( !this.initStatusOK || !this.useSessions ) >+ throw new Error( >+ 'Pz2.js: Ping not allowed (proxy mode) or session not initialized.' >+ ); >+ var context = this; >+ >+ clearTimeout(context.pingTimer); >+ >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ request.safeGet( >+ { "command": "ping", "session": this.sessionID, "windowid" : window.name }, >+ function(data) { >+ if ( data.getElementsByTagName("status")[0] >+ .childNodes[0].nodeValue == "OK" ) { >+ context.pingStatusOK = true; >+ context.pingTimer = >+ setTimeout( >+ function () { >+ context.ping(); >+ }, >+ context.keepAlive >+ ); >+ } >+ else >+ context.throwError('Ping failed. Malformed WS resonse.', >+ 111); >+ } >+ ); >+ }, >+ search: function (query, num, sort, filter, showfrom, addParamsArr) >+ { >+ clearTimeout(this.statTimer); >+ clearTimeout(this.showTimer); >+ clearTimeout(this.termTimer); >+ clearTimeout(this.bytargetTimer); >+ >+ this.showCounter = 0; >+ this.termCounter = 0; >+ this.bytargetCounter = 0; >+ this.statCounter = 0; >+ this.activeClients = 1; >+ >+ // no proxy mode >+ if( !this.initStatusOK ) >+ throw new Error('Pz2.js: session not initialized.'); >+ >+ if( query !== undefined ) >+ this.currQuery = query; >+ else >+ throw new Error("Pz2.js: no query supplied to the search command."); >+ >+ if ( showfrom !== undefined ) >+ var start = showfrom; >+ else >+ var start = 0; >+ >+ var searchParams = { >+ "command": "search", >+ "query": this.currQuery, >+ "session": this.sessionID, >+ "windowid" : window.name >+ }; >+ >+ if( sort !== undefined ) { >+ this.currentSort = sort; >+ searchParams["sort"] = sort; >+ } >+ if (filter !== undefined) >+ searchParams["filter"] = filter; >+ >+ // copy additional parmeters, do not overwrite >+ if (addParamsArr != undefined) { >+ for (var prop in addParamsArr) { >+ if (!searchParams.hasOwnProperty(prop)) >+ searchParams[prop] = addParamsArr[prop]; >+ } >+ } >+ >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ request.safeGet( >+ searchParams, >+ function(data) { >+ if ( data.getElementsByTagName("status")[0] >+ .childNodes[0].nodeValue == "OK" ) { >+ context.searchStatusOK = true; >+ //piggyback search >+ context.show(start, num, sort); >+ if (context.statCallback) >+ context.stat(); >+ if (context.termlistCallback) >+ context.termlist(); >+ if (context.bytargetCallback) >+ context.bytarget(); >+ } >+ else >+ context.throwError('Search failed. Malformed WS resonse.', >+ 112); >+ } >+ ); >+ }, >+ stat: function() >+ { >+ if( !this.initStatusOK ) >+ throw new Error('Pz2.js: session not initialized.'); >+ >+ // if called explicitly takes precedence >+ clearTimeout(this.statTimer); >+ >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ request.safeGet( >+ { "command": "stat", "session": this.sessionID, "windowid" : window.name }, >+ function(data) { >+ if ( data.getElementsByTagName("stat") ) { >+ var activeClients = >+ Number( data.getElementsByTagName("activeclients")[0] >+ .childNodes[0].nodeValue ); >+ context.activeClients = activeClients; >+ >+ var stat = Element_parseChildNodes(data.documentElement); >+ >+ context.statCounter++; >+ var delay = context.statTime >+ + context.statCounter * context.dumpFactor; >+ >+ if ( activeClients > 0 ) >+ context.statTimer = >+ setTimeout( >+ function () { >+ context.stat(); >+ }, >+ delay >+ ); >+ context.statCallback(stat); >+ } >+ else >+ context.throwError('Stat failed. Malformed WS resonse.', >+ 113); >+ } >+ ); >+ }, >+ show: function(start, num, sort, query_state) >+ { >+ if( !this.searchStatusOK && this.useSessions ) >+ throw new Error( >+ 'Pz2.js: show command has to be preceded with a search command.' >+ ); >+ >+ // if called explicitly takes precedence >+ clearTimeout(this.showTimer); >+ >+ if( sort !== undefined ) >+ this.currentSort = sort; >+ if( start !== undefined ) >+ this.currentStart = Number( start ); >+ if( num !== undefined ) >+ this.currentNum = Number( num ); >+ >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ var requestParameters = >+ { >+ "command": "show", >+ "session": this.sessionID, >+ "start": this.currentStart, >+ "num": this.currentNum, >+ "sort": this.currentSort, >+ "block": 1, >+ "type": this.showResponseType, >+ "windowid" : window.name >+ }; >+ if (query_state) >+ requestParameters["query-state"] = query_state; >+ if (this.version && this.version > 0) >+ requestParameters["version"] = this.version; >+ request.safeGet( >+ requestParameters, >+ function(data, type) { >+ var show = null; >+ var activeClients = 0; >+ if (type === "json") { >+ show = {}; >+ activeClients = Number(data.activeclients[0]); >+ show.activeclients = activeClients; >+ show.merged = Number(data.merged[0]); >+ show.total = Number(data.total[0]); >+ show.start = Number(data.start[0]); >+ show.num = Number(data.num[0]); >+ show.hits = data.hit; >+ } else if (data.getElementsByTagName("status")[0] >+ .childNodes[0].nodeValue == "OK") { >+ // first parse the status data send along with records >+ // this is strictly bound to the format >+ activeClients = >+ Number(data.getElementsByTagName("activeclients")[0] >+ .childNodes[0].nodeValue); >+ show = { >+ "activeclients": activeClients, >+ "merged": >+ Number( data.getElementsByTagName("merged")[0] >+ .childNodes[0].nodeValue ), >+ "total": >+ Number( data.getElementsByTagName("total")[0] >+ .childNodes[0].nodeValue ), >+ "start": >+ Number( data.getElementsByTagName("start")[0] >+ .childNodes[0].nodeValue ), >+ "num": >+ Number( data.getElementsByTagName("num")[0] >+ .childNodes[0].nodeValue ), >+ "hits": [] >+ }; >+ // parse all the first-level nodes for all <hit> tags >+ var hits = data.getElementsByTagName("hit"); >+ for (i = 0; i < hits.length; i++) >+ show.hits[i] = Element_parseChildNodes(hits[i]); >+ } else { >+ context.throwError('Show failed. Malformed WS resonse.', >+ 114); >+ }; >+ >+ var approxNode = data.getElementsByTagName("approximation"); >+ if (approxNode && approxNode[0] && approxNode[0].childNodes[0] && approxNode[0].childNodes[0].nodeValue) >+ show['approximation'] = >+ Number( approxNode[0].childNodes[0].nodeValue); >+ >+ >+ data.getElementsByTagName("") >+ context.activeClients = activeClients; >+ context.showCounter++; >+ var delay = context.showTime; >+ if (context.showCounter > context.showFastCount) >+ delay += context.showCounter * context.dumpFactor; >+ if ( activeClients > 0 ) >+ context.showTimer = setTimeout( >+ function () { >+ context.show(); >+ }, >+ delay); >+ context.showCallback(show); >+ } >+ ); >+ }, >+ record: function(id, offset, syntax, handler) >+ { >+ // we may call record with no previous search if in proxy mode >+ if(!this.searchStatusOK && this.useSessions) >+ throw new Error( >+ 'Pz2.js: record command has to be preceded with a search command.' >+ ); >+ >+ if( id !== undefined ) >+ this.currRecID = id; >+ >+ var recordParams = { >+ "command": "record", >+ "session": this.sessionID, >+ "id": this.currRecID, >+ "windowid" : window.name >+ }; >+ >+ this.currRecOffset = null; >+ if (offset != undefined) { >+ recordParams["offset"] = offset; >+ this.currRecOffset = offset; >+ } >+ >+ if (syntax != undefined) >+ recordParams['syntax'] = syntax; >+ >+ //overwrite default callback id needed >+ var callback = this.recordCallback; >+ var args = undefined; >+ if (handler != undefined) { >+ callback = handler['callback']; >+ args = handler['args']; >+ } >+ >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ >+ request.safeGet( >+ recordParams, >+ function(data) { >+ var recordNode; >+ var record; >+ //raw record >+ if (context.currRecOffset !== null) { >+ record = new Array(); >+ record['xmlDoc'] = data; >+ record['offset'] = context.currRecOffset; >+ callback(record, args); >+ //pz2 record >+ } else if ( recordNode = >+ data.getElementsByTagName("record")[0] ) { >+ // if stylesheet was fetched do not parse the response >+ if ( context.xslDoc ) { >+ record = new Array(); >+ record['xmlDoc'] = data; >+ record['xslDoc'] = context.xslDoc; >+ record['recid'] = >+ recordNode.getElementsByTagName("recid")[0] >+ .firstChild.nodeValue; >+ //parse record >+ } else { >+ record = Element_parseChildNodes(recordNode); >+ } >+ var activeClients = >+ Number( data.getElementsByTagName("activeclients")[0] >+ .childNodes[0].nodeValue ); >+ context.activeClients = activeClients; >+ context.recordCounter++; >+ var delay = context.recordTime + context.recordCounter * context.dumpFactor; >+ if ( activeClients > 0 ) >+ context.recordTimer = >+ setTimeout ( >+ function() { >+ context.record(id, offset, syntax, handler); >+ }, >+ delay >+ ); >+ callback(record, args); >+ } >+ else >+ context.throwError('Record failed. Malformed WS resonse.', >+ 115); >+ } >+ ); >+ }, >+ >+ termlist: function() >+ { >+ if( !this.searchStatusOK && this.useSessions ) >+ throw new Error( >+ 'Pz2.js: termlist command has to be preceded with a search command.' >+ ); >+ >+ // if called explicitly takes precedence >+ clearTimeout(this.termTimer); >+ >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ request.safeGet( >+ { >+ "command": "termlist", >+ "session": this.sessionID, >+ "name": this.termKeys, >+ "windowid" : window.name, >+ "version" : this.version >+ >+ }, >+ function(data) { >+ if ( data.getElementsByTagName("termlist") ) { >+ var activeClients = >+ Number( data.getElementsByTagName("activeclients")[0] >+ .childNodes[0].nodeValue ); >+ context.activeClients = activeClients; >+ var termList = { "activeclients": activeClients }; >+ var termLists = data.getElementsByTagName("list"); >+ //for each termlist >+ for (i = 0; i < termLists.length; i++) { >+ var listName = termLists[i].getAttribute('name'); >+ termList[listName] = new Array(); >+ var terms = termLists[i].getElementsByTagName('term'); >+ //for each term in the list >+ for (j = 0; j < terms.length; j++) { >+ var term = { >+ "name": >+ (terms[j].getElementsByTagName("name")[0] >+ .childNodes.length >+ ? terms[j].getElementsByTagName("name")[0] >+ .childNodes[0].nodeValue >+ : 'ERROR'), >+ "freq": >+ terms[j] >+ .getElementsByTagName("frequency")[0] >+ .childNodes[0].nodeValue || 'ERROR' >+ }; >+ >+ // Only for xtargets: id, records, filtered >+ var termIdNode = >+ terms[j].getElementsByTagName("id"); >+ if(terms[j].getElementsByTagName("id").length) >+ term["id"] = >+ termIdNode[0].childNodes[0].nodeValue; >+ termList[listName][j] = term; >+ >+ var recordsNode = terms[j].getElementsByTagName("records"); >+ if (recordsNode && recordsNode.length) >+ term["records"] = recordsNode[0].childNodes[0].nodeValue; >+ >+ var filteredNode = terms[j].getElementsByTagName("filtered"); >+ if (filteredNode && filteredNode.length) >+ term["filtered"] = filteredNode[0].childNodes[0].nodeValue; >+ >+ } >+ } >+ >+ context.termCounter++; >+ var delay = context.termTime >+ + context.termCounter * context.dumpFactor; >+ if ( activeClients > 0 ) >+ context.termTimer = >+ setTimeout( >+ function () { >+ context.termlist(); >+ }, >+ delay >+ ); >+ >+ context.termlistCallback(termList); >+ } >+ else >+ context.throwError('Termlist failed. Malformed WS resonse.', >+ 116); >+ } >+ ); >+ >+ }, >+ bytarget: function() >+ { >+ if( !this.initStatusOK && this.useSessions ) >+ throw new Error( >+ 'Pz2.js: bytarget command has to be preceded with a search command.' >+ ); >+ >+ // no need to continue >+ if( !this.searchStatusOK ) >+ return; >+ >+ // if called explicitly takes precedence >+ clearTimeout(this.bytargetTimer); >+ >+ var context = this; >+ var request = new pzHttpRequest(this.pz2String, this.errorHandler); >+ request.safeGet( >+ { >+ "command": "bytarget", >+ "session": this.sessionID, >+ "block": 1, >+ "windowid" : window.name, >+ "version" : this.version >+ }, >+ function(data) { >+ if ( data.getElementsByTagName("status")[0] >+ .childNodes[0].nodeValue == "OK" ) { >+ var targetNodes = data.getElementsByTagName("target"); >+ var bytarget = new Array(); >+ for ( i = 0; i < targetNodes.length; i++) { >+ bytarget[i] = new Array(); >+ for( j = 0; j < targetNodes[i].childNodes.length; j++ ) { >+ if ( targetNodes[i].childNodes[j].nodeType >+ == Node.ELEMENT_NODE ) { >+ var nodeName = >+ targetNodes[i].childNodes[j].nodeName; >+ if (targetNodes[i].childNodes[j].firstChild != null) >+ { >+ var nodeText = targetNodes[i].childNodes[j] >+ .firstChild.nodeValue; >+ bytarget[i][nodeName] = nodeText; >+ } >+ else { >+ bytarget[i][nodeName] = ""; >+ } >+ >+ >+ } >+ } >+ if (bytarget[i]["state"]=="Client_Disconnected") { >+ bytarget[i]["hits"] = "Error"; >+ } else if (bytarget[i]["state"]=="Client_Error") { >+ bytarget[i]["hits"] = "Error"; >+ } else if (bytarget[i]["state"]=="Client_Working") { >+ bytarget[i]["hits"] = "..."; >+ } >+ if (bytarget[i].diagnostic == "1") { >+ bytarget[i].diagnostic = "Permanent system error"; >+ } else if (bytarget[i].diagnostic == "2") { >+ bytarget[i].diagnostic = "Temporary system error"; >+ } >+ var targetsSuggestions = targetNodes[i].getElementsByTagName("suggestions"); >+ if (targetsSuggestions != undefined && targetsSuggestions.length>0) { >+ var suggestions = targetsSuggestions[0]; >+ bytarget[i]["suggestions"] = Element_parseChildNodes(suggestions); >+ } >+ } >+ >+ context.bytargetCounter++; >+ var delay = context.bytargetTime >+ + context.bytargetCounter * context.dumpFactor; >+ if ( context.activeClients > 0 ) >+ context.bytargetTimer = >+ setTimeout( >+ function () { >+ context.bytarget(); >+ }, >+ delay >+ ); >+ >+ context.bytargetCallback(bytarget); >+ } >+ else >+ context.throwError('Bytarget failed. Malformed WS resonse.', >+ 117); >+ } >+ ); >+ }, >+ >+ // just for testing, probably shouldn't be here >+ showNext: function(page) >+ { >+ var step = page || 1; >+ this.show( ( step * this.currentNum ) + this.currentStart ); >+ }, >+ >+ showPrev: function(page) >+ { >+ if (this.currentStart == 0 ) >+ return false; >+ var step = page || 1; >+ var newStart = this.currentStart - (step * this.currentNum ); >+ this.show( newStart > 0 ? newStart : 0 ); >+ }, >+ >+ showPage: function(pageNum) >+ { >+ //var page = pageNum || 1; >+ this.show(pageNum * this.currentNum); >+ } >+}; >+ >+/* >+******************************************************************************** >+** AJAX HELPER CLASS *********************************************************** >+******************************************************************************** >+*/ >+var pzHttpRequest = function ( url, errorHandler ) { >+ this.maxUrlLength = 2048; >+ this.request = null; >+ this.url = url; >+ this.errorHandler = errorHandler || null; >+ this.async = true; >+ this.requestHeaders = {}; >+ >+ if ( window.XMLHttpRequest ) { >+ this.request = new XMLHttpRequest(); >+ } else if ( window.ActiveXObject ) { >+ try { >+ this.request = new ActiveXObject( 'Msxml2.XMLHTTP' ); >+ } catch (err) { >+ this.request = new ActiveXObject( 'Microsoft.XMLHTTP' ); >+ } >+ } >+}; >+ >+ >+pzHttpRequest.prototype = >+{ >+ safeGet: function ( params, callback ) >+ { >+ var encodedParams = this.encodeParams(params); >+ var url = this._urlAppendParams(encodedParams); >+ if (url.length >= this.maxUrlLength) { >+ this.requestHeaders["Content-Type"] >+ = "application/x-www-form-urlencoded"; >+ this._send( 'POST', this.url, encodedParams, callback ); >+ } else { >+ this._send( 'GET', url, '', callback ); >+ } >+ }, >+ >+ get: function ( params, callback ) >+ { >+ this._send( 'GET', this._urlAppendParams(this.encodeParams(params)), >+ '', callback ); >+ }, >+ >+ post: function ( params, data, callback ) >+ { >+ this._send( 'POST', this._urlAppendParams(this.encodeParams(params)), >+ data, callback ); >+ }, >+ >+ load: function () >+ { >+ this.async = false; >+ this.request.open( 'GET', this.url, this.async ); >+ this.request.send(''); >+ if ( this.request.status == 200 ) >+ return this.request.responseXML; >+ }, >+ >+ encodeParams: function (params) >+ { >+ var sep = ""; >+ var encoded = ""; >+ for (var key in params) { >+ if (params[key] != null) { >+ encoded += sep + key + '=' + encodeURIComponent(params[key]); >+ sep = '&'; >+ } >+ } >+ return encoded; >+ }, >+ >+ _send: function ( type, url, data, callback) >+ { >+ var context = this; >+ this.callback = callback; >+ this.async = true; >+ this.request.open( type, url, this.async ); >+ for (var key in this.requestHeaders) >+ this.request.setRequestHeader(key, this.requestHeaders[key]); >+ this.request.onreadystatechange = function () { >+ context._handleResponse(url); /// url used ONLY for error reporting >+ } >+ this.request.send(data); >+ }, >+ >+ _urlAppendParams: function (encodedParams) >+ { >+ if (encodedParams) >+ return this.url + "?" + encodedParams; >+ else >+ return this.url; >+ }, >+ >+ _handleResponse: function (savedUrlForErrorReporting) >+ { >+ if ( this.request.readyState == 4 ) { >+ // pick up appplication errors first >+ var errNode = null; >+ if (this.request.responseXML && >+ (errNode = this.request.responseXML.documentElement) >+ && errNode.nodeName == 'error') { >+ var errMsg = errNode.getAttribute("msg"); >+ var errCode = errNode.getAttribute("code"); >+ var errAddInfo = ''; >+ if (errNode.childNodes.length) >+ errAddInfo = ': ' + errNode.childNodes[0].nodeValue; >+ >+ var err = new Error(errMsg + errAddInfo); >+ err.code = errCode; >+ >+ if (this.errorHandler) { >+ this.errorHandler(err); >+ } >+ else { >+ throw err; >+ } >+ } else if (this.request.status == 200 && >+ this.request.responseXML == null) { >+ if (this.request.responseText != null) { >+ //assume JSON >+ >+ var json = null; >+ var text = this.request.responseText; >+ if (typeof window.JSON == "undefined") >+ json = eval("(" + text + ")"); >+ else { >+ try { >+ json = JSON.parse(text); >+ } >+ catch (e) { >+ // Safari: eval will fail as well. Considering trying JSON2 (non-native implementation) instead >+ /* DEBUG only works in mk2-mobile >+ if (document.getElementById("log")) >+ document.getElementById("log").innerHTML = "" + e + " " + length + ": " + text; >+ */ >+ try { >+ json = eval("(" + text + ")"); >+ } >+ catch (e) { >+ /* DEBUG only works in mk2-mobile >+ if (document.getElementById("log")) >+ document.getElementById("log").innerHTML = "" + e + " " + length + ": " + text; >+ */ >+ } >+ } >+ } >+ this.callback(json, "json"); >+ } else { >+ var err = new Error("XML response is empty but no error " + >+ "for " + savedUrlForErrorReporting); >+ err.code = -1; >+ if (this.errorHandler) { >+ this.errorHandler(err); >+ } else { >+ throw err; >+ } >+ } >+ } else if (this.request.status == 200) { >+ this.callback(this.request.responseXML); >+ } else { >+ var err = new Error("HTTP response not OK: " >+ + this.request.status + " - " >+ + this.request.statusText ); >+ err.code = '00' + this.request.status; >+ if (this.errorHandler) { >+ this.errorHandler(err); >+ } >+ else { >+ throw err; >+ } >+ } >+ } >+ } >+}; >+ >+/* >+******************************************************************************** >+** XML HELPER FUNCTIONS ******************************************************** >+******************************************************************************** >+*/ >+ >+// DOMDocument >+ >+if ( window.ActiveXObject) { >+ var DOMDoc = document; >+} else { >+ var DOMDoc = Document.prototype; >+} >+ >+DOMDoc.newXmlDoc = function ( root ) >+{ >+ var doc; >+ >+ if (document.implementation && document.implementation.createDocument) { >+ doc = document.implementation.createDocument('', root, null); >+ } else if ( window.ActiveXObject ) { >+ doc = new ActiveXObject("MSXML2.DOMDocument"); >+ doc.loadXML('<' + root + '/>'); >+ } else { >+ throw new Error ('No XML support in this browser'); >+ } >+ >+ return doc; >+} >+ >+ >+DOMDoc.parseXmlFromString = function ( xmlString ) >+{ >+ var doc; >+ >+ if ( window.DOMParser ) { >+ var parser = new DOMParser(); >+ doc = parser.parseFromString( xmlString, "text/xml"); >+ } else if ( window.ActiveXObject ) { >+ doc = new ActiveXObject("MSXML2.DOMDocument"); >+ doc.loadXML( xmlString ); >+ } else { >+ throw new Error ("No XML parsing support in this browser."); >+ } >+ >+ return doc; >+} >+ >+DOMDoc.transformToDoc = function (xmlDoc, xslDoc) >+{ >+ if ( window.XSLTProcessor ) { >+ var proc = new XSLTProcessor(); >+ proc.importStylesheet( xslDoc ); >+ return proc.transformToDocument(xmlDoc); >+ } else if ( window.ActiveXObject ) { >+ return document.parseXmlFromString(xmlDoc.transformNode(xslDoc)); >+ } else { >+ alert( 'Unable to perform XSLT transformation in this browser' ); >+ } >+} >+ >+// DOMElement >+ >+Element_removeFromDoc = function (DOM_Element) >+{ >+ DOM_Element.parentNode.removeChild(DOM_Element); >+} >+ >+Element_emptyChildren = function (DOM_Element) >+{ >+ while( DOM_Element.firstChild ) { >+ DOM_Element.removeChild( DOM_Element.firstChild ) >+ } >+} >+ >+Element_appendTransformResult = function ( DOM_Element, xmlDoc, xslDoc ) >+{ >+ if ( window.XSLTProcessor ) { >+ var proc = new XSLTProcessor(); >+ proc.importStylesheet( xslDoc ); >+ var docFrag = false; >+ docFrag = proc.transformToFragment( xmlDoc, DOM_Element.ownerDocument ); >+ DOM_Element.appendChild(docFrag); >+ } else if ( window.ActiveXObject ) { >+ DOM_Element.innerHTML = xmlDoc.transformNode( xslDoc ); >+ } else { >+ alert( 'Unable to perform XSLT transformation in this browser' ); >+ } >+} >+ >+Element_appendTextNode = function (DOM_Element, tagName, textContent ) >+{ >+ var node = DOM_Element.ownerDocument.createElement(tagName); >+ var text = DOM_Element.ownerDocument.createTextNode(textContent); >+ >+ DOM_Element.appendChild(node); >+ node.appendChild(text); >+ >+ return node; >+} >+ >+Element_setTextContent = function ( DOM_Element, textContent ) >+{ >+ if (typeof DOM_Element.textContent !== "undefined") { >+ DOM_Element.textContent = textContent; >+ } else if (typeof DOM_Element.innerText !== "undefined" ) { >+ DOM_Element.innerText = textContent; >+ } else { >+ throw new Error("Cannot set text content of the node, no such method."); >+ } >+} >+ >+Element_getTextContent = function (DOM_Element) >+{ >+ if ( typeof DOM_Element.textContent != 'undefined' ) { >+ return DOM_Element.textContent; >+ } else if (typeof DOM_Element.text != 'undefined') { >+ return DOM_Element.text; >+ } else { >+ throw new Error("Cannot get text content of the node, no such method."); >+ } >+} >+ >+Element_parseChildNodes = function (node) >+{ >+ var parsed = {}; >+ var hasChildElems = false; >+ var textContent = ''; >+ >+ if (node.hasChildNodes()) { >+ var children = node.childNodes; >+ for (var i = 0; i < children.length; i++) { >+ var child = children[i]; >+ switch (child.nodeType) { >+ case Node.ELEMENT_NODE: >+ hasChildElems = true; >+ var nodeName = child.nodeName; >+ if (!(nodeName in parsed)) >+ parsed[nodeName] = []; >+ parsed[nodeName].push(Element_parseChildNodes(child)); >+ break; >+ case Node.TEXT_NODE: >+ textContent += child.nodeValue; >+ break; >+ case Node.CDATA_SECTION_NODE: >+ textContent += child.nodeValue; >+ break; >+ } >+ } >+ } >+ >+ var attrs = node.attributes; >+ for (var i = 0; i < attrs.length; i++) { >+ hasChildElems = true; >+ var attrName = '@' + attrs[i].nodeName; >+ var attrValue = attrs[i].nodeValue; >+ parsed[attrName] = attrValue; >+ } >+ >+ // if no nested elements/attrs set value to text >+ if (hasChildElems) >+ parsed['#text'] = textContent; >+ else >+ parsed = textContent; >+ >+ return parsed; >+} >+ >+/* do not remove trailing bracket */ >+} >diff --git a/koha-tmpl/opac-tmpl/prog/en/css/opac.css b/koha-tmpl/opac-tmpl/prog/en/css/opac.css >index c2902c1..e1838b49 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css >+++ b/koha-tmpl/opac-tmpl/prog/en/css/opac.css >@@ -1690,6 +1690,10 @@ strong em, em strong { > vertical-align: top; > width: 10px; > } >+.sourcecol { >+ vertical-align: top; >+ width: 100px; >+} > #container { > color : #000; > } >@@ -3017,6 +3021,16 @@ float:left; > padding: 0.1em 0; > } > >+.notesrow label { >+ font-weight: bold; >+} >+.notesrow span { >+ display: block; >+} >+.notesrow textarea { >+ width: 100%; >+} >+ > .thumbnail-shelfbrowser span { > margin: 0px auto; > } >@@ -3041,7 +3055,7 @@ padding: 0.1em 0; > background: #EEEEEE none; > } > >-#overdrive-results { >+#overdrive-results, #pazpar2-results { > font-weight: bold; > padding-left: 1em; > } >@@ -3080,3 +3094,14 @@ padding: 0.1em 0; > .copiesrow { > clear : both; > } >+ >+.thumbnail-shelfbrowser span { >+ margin: 0px auto; >+} >+ >+#modal-overlay { >+ background-color: white; >+ border-radius: 5px; >+ max-width: 75%; >+ padding: 15px; >+} >diff --git a/koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js b/koha-tmpl/opac-tmpl/prog/en/js/externalsearch.js >new file mode 100644 >index 0000000..b2fe4a7 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/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/prog/en/lib/jquery/plugins/jquery.lightbox_me.js b/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.lightbox_me.js >new file mode 100644 >index 0000000..effe8a6 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/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 = $('<iframe id="foo" style="z-index: ' + (opts.zIndex + 1) + ';border: none; margin: 0; padding: 0; position: absolute; width: 100%; height: 100%; top: 0; left: 0; filter: mask();"/>'), >+ ie6 = ($.browser.msie && $.browser.version < 7); >+ >+ if (opts.showOverlay) { >+ //check if there's an existing overlay, if so, make subequent ones clear >+ var $currentOverlays = $(".js_lb_overlay:visible"); >+ if ($currentOverlays.length > 0){ >+ $overlay = $('<div class="lb_overlay_clear js_lb_overlay"/>'); >+ } else { >+ $overlay = $('<div class="' + opts.classPrefix + '_overlay js_lb_overlay"/>'); >+ } >+ } >+ >+ /*---------------------------------------------------- >+ DOM Building >+ ---------------------------------------------------- */ >+ if (ie6) { >+ var src = /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'; >+ $iframe.attr('src', src); >+ $('body').append($iframe); >+ } // iframe shim for ie6, to hide select elements >+ $('body').append($self.hide()).append($overlay); >+ >+ >+ /*---------------------------------------------------- >+ Overlay CSS stuffs >+ ---------------------------------------------------- */ >+ >+ // set css of the overlay >+ if (opts.showOverlay) { >+ setOverlayHeight(); // pulled this into a function because it is called on window resize. >+ $overlay.css({ position: 'absolute', width: '100%', top: 0, left: 0, right: 0, bottom: 0, zIndex: (opts.zIndex + 2), display: 'none' }); >+ if (!$overlay.hasClass('lb_overlay_clear')){ >+ $overlay.css(opts.overlayCSS); >+ } >+ } >+ >+ /*---------------------------------------------------- >+ Animate it in. >+ ---------------------------------------------------- */ >+ // >+ if (opts.showOverlay) { >+ $overlay.fadeIn(opts.overlaySpeed, function() { >+ setSelfPosition(); >+ $self[opts.appearEffect](opts.lightboxSpeed, function() { setOverlayHeight(); setSelfPosition(); opts.onLoad()}); >+ }); >+ } else { >+ setSelfPosition(); >+ $self[opts.appearEffect](opts.lightboxSpeed, function() { opts.onLoad()}); >+ } >+ >+ /*---------------------------------------------------- >+ Hide parent if parent specified (parentLightbox should be jquery reference to any parent lightbox) >+ ---------------------------------------------------- */ >+ if (opts.parentLightbox) { >+ opts.parentLightbox.fadeOut(200); >+ } >+ >+ >+ /*---------------------------------------------------- >+ Bind Events >+ ---------------------------------------------------- */ >+ >+ $(window).resize(setOverlayHeight) >+ .resize(setSelfPosition) >+ .scroll(setSelfPosition); >+ >+ $(window).bind('keyup.lightbox_me', observeKeyPress); >+ >+ if (opts.closeClick) { >+ $overlay.click(function(e) { closeLightbox(); e.preventDefault; }); >+ } >+ $self.delegate(opts.closeSelector, "click", function(e) { >+ closeLightbox(); e.preventDefault(); >+ }); >+ $self.bind('close', closeLightbox); >+ $self.bind('reposition', setSelfPosition); >+ >+ >+ >+ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- >+ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ >+ >+ >+ /*---------------------------------------------------- >+ Private Functions >+ ---------------------------------------------------- */ >+ >+ /* Remove or hide all elements */ >+ function closeLightbox() { >+ var s = $self[0].style; >+ if (opts.destroyOnClose) { >+ $self.add($overlay).remove(); >+ } else { >+ $self.add($overlay).hide(); >+ } >+ >+ //show the hidden parent lightbox >+ if (opts.parentLightbox) { >+ opts.parentLightbox.fadeIn(200); >+ } >+ >+ $iframe.remove(); >+ >+ // clean up events. >+ $self.undelegate(opts.closeSelector, "click"); >+ >+ $(window).unbind('reposition', setOverlayHeight); >+ $(window).unbind('reposition', setSelfPosition); >+ $(window).unbind('scroll', setSelfPosition); >+ $(window).unbind('keyup.lightbox_me'); >+ if (ie6) >+ s.removeExpression('top'); >+ opts.onClose(); >+ } >+ >+ >+ /* Function to bind to the window to observe the escape/enter key press */ >+ function observeKeyPress(e) { >+ if((e.keyCode == 27 || (e.DOM_VK_ESCAPE == 27 && e.which==0)) && opts.closeEsc) closeLightbox(); >+ } >+ >+ >+ /* Set the height of the overlay >+ : if the document height is taller than the window, then set the overlay height to the document height. >+ : otherwise, just set overlay height: 100% >+ */ >+ function setOverlayHeight() { >+ if ($(window).height() < $(document).height()) { >+ $overlay.css({height: $(document).height() + 'px'}); >+ $iframe.css({height: $(document).height() + 'px'}); >+ } else { >+ $overlay.css({height: '100%'}); >+ if (ie6) { >+ $('html,body').css('height','100%'); >+ $iframe.css('height', '100%'); >+ } // ie6 hack for height: 100%; TODO: handle this in IE7 >+ } >+ } >+ >+ >+ /* Set the position of the modal'd window ($self) >+ : if $self is taller than the window, then make it absolutely positioned >+ : otherwise fixed >+ */ >+ function setSelfPosition() { >+ var s = $self[0].style; >+ >+ // reset CSS so width is re-calculated for margin-left CSS >+ $self.css({left: '50%', marginLeft: ($self.outerWidth() / 2) * -1, zIndex: (opts.zIndex + 3) }); >+ >+ >+ /* we have to get a little fancy when dealing with height, because lightbox_me >+ is just so fancy. >+ */ >+ >+ // if the height of $self is bigger than the window and self isn't already position absolute >+ if (($self.height() + 80 >= $(window).height()) && ($self.css('position') != 'absolute' || ie6)) { >+ >+ // we are going to make it positioned where the user can see it, but they can still scroll >+ // so the top offset is based on the user's scroll position. >+ var topOffset = $(document).scrollTop() + 40; >+ $self.css({position: 'absolute', top: topOffset + 'px', marginTop: 0}) >+ if (ie6) { >+ s.removeExpression('top'); >+ } >+ } else if ($self.height()+ 80 < $(window).height()) { >+ //if the height is less than the window height, then we're gonna make this thing position: fixed. >+ // in ie6 we're gonna fake it. >+ if (ie6) { >+ s.position = 'absolute'; >+ if (opts.centered) { >+ s.setExpression('top', '(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"') >+ s.marginTop = 0; >+ } else { >+ var top = (opts.modalCSS && opts.modalCSS.top) ? parseInt(opts.modalCSS.top) : 0; >+ s.setExpression('top', '((blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"') >+ } >+ } else { >+ if (opts.centered) { >+ $self.css({ position: 'fixed', top: '50%', marginTop: ($self.outerHeight() / 2) * -1}) >+ } else { >+ $self.css({ position: 'fixed'}).css(opts.modalCSS); >+ } >+ >+ } >+ } >+ } >+ >+ }); >+ >+ >+ >+ }; >+ >+ $.fn.lightbox_me.defaults = { >+ >+ // animation >+ appearEffect: "fadeIn", >+ appearEase: "", >+ overlaySpeed: 250, >+ lightboxSpeed: 300, >+ >+ // close >+ closeSelector: ".close", >+ closeClick: true, >+ closeEsc: true, >+ >+ // behavior >+ destroyOnClose: false, >+ showOverlay: true, >+ parentLightbox: false, >+ >+ // callbacks >+ onLoad: function() {}, >+ onClose: function() {}, >+ >+ // style >+ classPrefix: 'lb', >+ zIndex: 999, >+ centered: false, >+ modalCSS: {top: '40px'}, >+ overlayCSS: {background: 'black', opacity: .3} >+ } >+})(jQuery); >\ No newline at end of file >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-external-search.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-external-search.tt >new file mode 100644 >index 0000000..c402209 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-external-search.tt >@@ -0,0 +1,240 @@ >+[% INCLUDE 'doc-head-open.inc' %] >+[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › External search for '[% q | html %]' >+[% INCLUDE 'doc-head-close.inc' %] >+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.lightbox_me.js"></script> >+<script type="text/javascript" src="/opac-tmpl/lib/pz2.js"></script> >+<script type="text/javascript" src="[% themelang %]/js/externalsearch.js"></script> >+<script type="text/javascript"> >+var querystring = "[% q |replace( "'", "\'" ) |replace( '\n', '\\n' ) |replace( '\r', '\\r' ) |html %]"; >+var results_per_page = [% OPACnumSearchResults %]; >+KOHA.ExternalSearch.targets = { >+ [% FOREACH target IN external_search_targets %] >+ '[% target.host %]:[% target.port %]/[% target.db %]': { >+ name: '[% target.name %]', >+ syntax: '[% target.syntax %]', >+ }, >+ [% END %] >+}; >+ >+var xsltResultStylesheets = { >+ [% FOREACH stylesheet IN xslt_result_stylesheets %] >+ '[% stylesheet.syntax %]': KOHA.XSLTGet( '[% stylesheet.url %]' ), >+ [% END %] >+}; >+ >+var xsltDetailStylesheets = { >+ [% FOREACH stylesheet IN xslt_detail_stylesheets %] >+ '[% stylesheet.syntax %]': KOHA.XSLTGet( '[% stylesheet.url %]' ), >+ [% END %] >+}; >+ >+var recordCache = {}; >+var resultRenderCache = {}; >+ >+function showResult( syntax, recid ) { >+ if ( recordCache[ recid ] ) { >+ done( recordCache[ recid ] ); >+ } else { >+ KOHA.ExternalSearch.GetDetailedRecord( recid, function( record ) { >+ done( recordCache[ recid ] = record.xmlDoc ); >+ } ); >+ } >+ >+ function done( record ) { >+ xsltResultStylesheets[ syntax ].done( function( xslDoc ) { >+ var fragment = resultRenderCache[ recid ] = KOHA.TransformToFragment( record, xslDoc ); >+ var $tr = $( '#results tr' ).filter( function() { return $( this ).data( 'recid' ) == recid } ); >+ $tr.find( '.info' ).html( fragment ); >+ $tr.find( 'a' ).attr( 'href', '#' ).click( function() { >+ showDetail( syntax, recid ); >+ >+ return false; >+ } ); >+ } ); >+ } >+} >+ >+function showDetail( syntax, recid ) { >+ var record = recordCache[ recid ]; >+ console.info((new XMLSerializer).serializeToString( record )); >+ >+ xsltDetailStylesheets[ syntax ].done( function( xslDoc ) { >+ var fragment = KOHA.TransformToFragment( record, xslDoc ); >+ >+ $( '#modal-overlay' ).html( fragment ).lightbox_me( { >+ centered: true, >+ } ); >+ } ); >+} >+ >+function search( offset, reset_search ) { >+ $( '#pazpar2-status' ).html( 'Searching external targets... <img class="throbber" src="/opac-tmpl/lib/jquery/plugins/themes/classic/throbber.gif" /></span>' ); >+ >+ if ( reset_search ) { >+ KOHA.ExternalSearch.Search( querystring, results_per_page, callback ); >+ } else { >+ KOHA.ExternalSearch.Fetch( offset, callback ); >+ } >+ >+ function callback( data ) { >+ if ( data.error ) { >+ $( '#pazpar2-status' ).html( '<strong class="unavailable">Error searching external targets.</strong>' ); >+ return; >+ } >+ >+ if ( !data.total ) { >+ $( '#pazpar2-status' ).html( '<strong>No results found in the external targets.</strong>' ); >+ return; >+ } >+ >+ $( '#results tbody' ).empty(); >+ >+ $( '#pazpar2-status' ).html( '<strong>' + _( 'Found ' ) + data.total + _( ' results in ' ) + $( '#targets-facet input:checked' ).length + _( ' external targets.' ) + '</strong>' ); >+ >+ for ( var i = 0; data.hits[i]; i++ ) { >+ var hit = data.hits[i]; >+ var results = []; >+ var recordSyntax = KOHA.ExternalSearch.targets[ hit.location[0]['@id'] ].syntax; >+ >+ results.push( '<tr>' ); >+ >+ results.push( '<td class="sourcecol">', hit.location[0]['@name'], '</td>' ); >+ >+ results.push( '<td class="info">' ); >+ >+ if ( resultRenderCache[ hit.recid[0] ] ) { >+ results.push( resultRenderCache[ hit.recid[0] ] ); >+ } else { >+ results.push( hit['md-work-title'] ? hit['md-work-title'][0] : 'Loading...' ); >+ showResult( recordSyntax, hit.recid[0] ); >+ } >+ >+ results.push( '</td>' ); >+ >+ results.push( '</tr>' ); >+ var $tr = $( results.join( '' ) ); >+ $tr.data( 'recid', hit.recid[0] ); >+ $( '#results tbody' ).append( $tr ); >+ >+ ( function( hit, recordSyntax ) { >+ $tr.find( 'a' ).attr( 'href', '#' ).click( function() { >+ showDetail( recordSyntax, hit.recid[0] ); >+ >+ return false; >+ } ); >+ } )( hit, recordSyntax ); >+ } >+ >+ $( '#results tr:odd' ).addClass( 'highlight' ); >+ >+ var pages = []; >+ var cur_page = data.start / results_per_page; >+ var max_page = Math.floor( data.total / results_per_page ); >+ >+ if ( cur_page != 0 ) { >+ pages.push( '<a class="nav" href="#" data-offset="' + (offset - results_per_page) + '"><< Previous</a>' ); >+ } >+ >+ for ( var page = Math.max( 0, cur_page - 9 ); page <= Math.min( max_page, cur_page + 9 ); page++ ) { >+ if ( page == cur_page ) { >+ pages.push( ' <span class="current">' + ( page + 1 ) + '</span>' ); >+ } else { >+ pages.push( ' <a class="nav" href="#" data-offset="' + ( page * results_per_page ) + '">' + ( page + 1 ) + '</a>' ); >+ } >+ } >+ >+ if ( cur_page < max_page ) { >+ pages.push( ' <a class="nav" href="#" data-offset="' + (offset + results_per_page) + '">Next >></a>' ); >+ } >+ >+ if ( pages.length > 1 ) $( '#top-pages, #bottom-pages' ).find( '.pages' ).html( pages.join( '' ) ); >+ } >+} >+ >+$( document ).ready( function() { >+ $( '#breadcrumbs p' ) >+ .append( ' ' ) >+ .append( '<span id="pazpar2-status"></span>' ); >+ >+ $( document ).on( 'click', 'a.nav', function() { >+ search( $( this ).data( 'offset' ) ); >+ return false; >+ }); >+ >+ var reSearchTimeout; >+ >+ $( '#targets-facet input' ).each( function() { >+ $( this ).click( function() { >+ KOHA.ExternalSearch.targets[ $( this ).data( 'url' ) ].disabled = !this.checked; >+ >+ if ( reSearchTimeout ) clearTimeout( reSearchTimeout ); >+ >+ reSearchTimeout = setTimeout( function() { >+ if ( $( '#targets-facet input:checked' ).length ) search( 0, true ); >+ }, 1000 ); >+ } ); >+ >+ KOHA.ExternalSearch.targets[ $( this ).data( 'url' ) ].disabled = !this.checked; >+ } ); >+ >+ search( 0, true ); >+} ); >+</script> >+<style> >+.actions a.addtocart { >+ display: inline; >+} >+</style> >+</head> >+<body> >+<div id="doc3" class="yui-t1"> >+ >+<div id="bd"> >+ [% INCLUDE 'masthead.inc' %] >+ >+ <h1>External search for '[% q | html %]'</h1> >+ <div id="breadcrumbs"> >+ <p></p> >+ </div> >+ >+ <div id="yui-main"><div class="yui-b searchresults"> >+ <div id="top-pages"> >+ <div class="pages"> >+ </div> >+ </div> >+ <table id="results"> >+ <tbody> >+ </tbody> >+ </table> >+ <div id="bottom-pages"> >+ <div class="pages"> >+ </div> >+ </div> >+ </div></div> >+ >+ <div class="yui-b"><div id="facetcontainer" class="container"> >+ <div id="search-facets"> >+ >+ <h4>Refine your search</h4> >+ >+ <ul> >+ <li id="targets-facet"> >+ Targets >+ <ul> >+ [% FOREACH target = external_search_targets %] >+ <li> >+ <input data-url="[% target.host %]:[% target.port %]/[% target.db %]" type="checkbox" id="target-[% loop.index %]" checked /> >+ <label for="target-[% loop.index %]">[% target.name %] >+ </li> >+ [% END %] >+ </ul> >+ </li> >+ </ul> >+ </div> >+ </div></div> >+</div> >+ >+</div> >+ >+<div id="modal-overlay" style="display: none"></div> >+[% INCLUDE 'opac-bottom.inc' %] >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >index 9235b2b..e3c93ee 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >@@ -16,7 +16,11 @@ > <link rel="stylesheet" type="text/css" href="[% themelang %]/css/jquery.rating.css" /> > [% END %] > >-<script type="text/javascript" src="[% themelang %]/js/overdrive.js"></script> >+[% IF ( OverDriveEnabled ) %]<script type="text/javascript" src="[% themelang %]/js/overdrive.js"></script>[% END %] >+[% IF ( OPACSearchExternalTargets ) %] >+<script type="text/javascript" src="/opac-tmpl/lib/pz2.js"></script> >+<script type="text/javascript" src="[% themelang %]/js/externalsearch.js"></script> >+[% END %] > <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script> > [% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js"></script> > [% END %]<script type="text/javascript"> >@@ -266,24 +270,59 @@ $(document).ready(function(){ > $("#highlight_toggle_on" ).hide().click(function() {highlightOn() ;}); > $("#highlight_toggle_off").show().click(function() {highlightOff();}); > [% END %] >+ function StartExternalSearch(name, text) { >+ $( '#breadcrumbs p' ) >+ .eq( 0 ) >+ .append( ' <span id="' + name + '-results">' + text + '... <img class="throbber" src="/opac-tmpl/lib/jquery/plugins/themes/classic/throbber.gif" /></span>' ); >+ } >+ function FailExternalSearch( name, text ) { >+ $( '#' + name + '-results' ).html( text ); >+ } >+ function FinishExternalSearch( name, text, numItems, url ) { >+ if ( numItems ) { >+ $( '#' + name + '-results' ).html( text.replace( '__LINK__', '<a href="' + url + '">' + numItems + _(" results") + '</a>' ) ); >+ } else { >+ $( '#' + name + '-results' ).remove(); >+ } >+ } >+ > [% IF ( OverDriveEnabled ) %] >- var $overdrive_results = $( '<span id="overdrive-results">' + _( 'Searching OverDrive...' ) + ' <img class="throbber" src="/opac-tmpl/lib/jquery/plugins/themes/classic/throbber.gif" /></span>' ); >- $( '#breadcrumbs p' ).eq(0) >- .append( ' ' ) >- .append( $overdrive_results ); >+ StartExternalSearch( 'overdrive', _("Searching OverDrive") ); > KOHA.OverDrive.Search( "[% OverDriveLibraryID %]", querystring, 1, 0, function( data ) { > if ( data.error ) { >- $overdrive_results.html( _( 'Error searching OverDrive collection' ) ); >+ FailExternalSearch( 'overdrive', _("Error searching OverDrive collection") ); > return; > } > >- if ( data.totalItems ) { >- $overdrive_results.html( _( 'Found' ) + ' <a href="/cgi-bin/koha/opac-overdrive-search.pl?q=' + escape( querystring ) + '">' + data.totalItems + ' ' + _( 'results' ) + '</a> ' + _( 'in OverDrive collection' ) ); >- } else { >- $overdrive_results.remove(); >+ FinishExternalSearch( 'overdrive', _("Found __LINK__ in OverDrive collection"), data.totalItems, '/cgi-bin/koha/opac-overdrive-search.pl?q=' + escape( querystring ) ); >+ } ); >+ [% END %] >+ >+ [% IF ( OPACSearchExternalTargets ) %] >+ KOHA.ExternalSearch.targets = { >+ [% FOREACH target IN external_search_targets %] >+ '[% target.host %]:[% target.port %]/[% target.db %]': { >+ id: '[% target.target_id %]', >+ name: '[% target.name %]', >+ syntax: '[% target.syntax %]', >+ }, >+ [% END %] >+ }; >+ var num_targets = 0; $.each( KOHA.ExternalSearch.targets, function() { num_targets++ } ); >+ var first_succeeded; >+ >+ StartExternalSearch( 'pazpar2', _("Searching external targets") ); >+ KOHA.ExternalSearch.Search( querystring, 1, function( data ) { >+ if ( data.error ) { >+ if ( !first_succeeded ) FailExternalSearch( 'pazpar2', _("Error searching external targets") ); >+ return; > } >+ >+ first_succeeded = true; >+ FinishExternalSearch( 'pazpar2', _("Found __LINK__ in ") + num_targets + _(" external targets"), data.total, '/cgi-bin/koha/opac-external-search.pl?q=' + escape( querystring ) ); > } ); > [% END %] >+ > [% END %] > > [% IF ( TagsInputEnabled && loggedinusername ) %] >diff --git a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl >index addc7de..8d50984 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl >+++ b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slim2OPACResults.xsl >@@ -5,11 +5,13 @@ > xmlns:marc="http://www.loc.gov/MARC21/slim" > xmlns:items="http://www.koha-community.org/items" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >+ xmlns="http://www.w3.org/1999/xhtml" > exclude-result-prefixes="marc items"> > <xsl:import href="MARC21slimUtils.xsl"/> > <xsl:output method = "html" indent="yes" omit-xml-declaration = "yes" encoding="UTF-8"/> > <xsl:key name="item-by-status" match="items:item" use="items:status"/> > <xsl:key name="item-by-status-and-branch" match="items:item" use="concat(items:status, ' ', items:homebranch)"/> >+ <xsl:param name="showAvailability" select="true()"/> > > <xsl:template match="/"> > <xsl:apply-templates/> >@@ -1027,6 +1029,7 @@ > </xsl:for-each> > </span> > </xsl:if> >+ <xsl:if test="$showAvailability"> > <span class="results_summary availability"> > <span class="label">Availability: </span> > <xsl:choose> >@@ -1035,7 +1038,7 @@ > <xsl:when test="string-length($AlternateHoldingsField)=3 and marc:datafield[@tag=$AlternateHoldingsField]"> > <xsl:variable name="AlternateHoldingsCount" select="count(marc:datafield[@tag=$AlternateHoldingsField])"/> > <xsl:for-each select="marc:datafield[@tag=$AlternateHoldingsField][1]"> >- <xsl:call-template select="marc:datafield[@tag=$AlternateHoldingsField]" name="subfieldSelect"> >+ <xsl:call-template name="subfieldSelect"> > <xsl:with-param name="codes"><xsl:value-of select="$AlternateHoldingsSubfields"/></xsl:with-param> > <xsl:with-param name="delimeter"><xsl:value-of select="$AlternateHoldingsSeparator"/></xsl:with-param> > </xsl:call-template> >@@ -1143,6 +1146,7 @@ > <xsl:text>). </xsl:text> </span> > </xsl:if> > </span> >+ </xsl:if> > <xsl:choose> > <xsl:when test="($OPACItemLocation='location' or $OPACItemLocation='ccode') and (count(key('item-by-status', 'available'))!=0 or count(key('item-by-status', 'reference'))!=0)"> > <span class="results_summary" id="location"> >diff --git a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl >index df7c450..1f18054 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl >+++ b/koha-tmpl/opac-tmpl/prog/en/xslt/MARC21slimUtils.xsl >@@ -1,6 +1,6 @@ > <?xml version='1.0'?> > <!DOCTYPE stylesheet [<!ENTITY nbsp " " >]> >-<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> >+<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> > <xsl:template name="datafield"> > <xsl:param name="tag"/> > <xsl:param name="ind1"><xsl:text> </xsl:text></xsl:param> >diff --git a/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACResults.xsl b/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACResults.xsl >index ebf94b9..d115174 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACResults.xsl >+++ b/koha-tmpl/opac-tmpl/prog/en/xslt/UNIMARCslim2OPACResults.xsl >@@ -12,6 +12,7 @@ > <xsl:output method = "html" indent="yes" omit-xml-declaration = "yes" encoding="UTF-8"/> > <xsl:key name="item-by-status" match="items:item" use="items:status"/> > <xsl:key name="item-by-status-and-branch" match="items:item" use="concat(items:status, ' ', items:homebranch)"/> >+<xsl:param name="showAvailability" select="true()"/> > > <xsl:template match="/"> > <xsl:apply-templates/> >@@ -99,6 +100,7 @@ > > <xsl:call-template name="tag_215" /> > >+ <xsl:if test="$showAvailability"> > <span class="results_summary availability"> > <span class="label">Availability: </span> > <xsl:choose> >@@ -245,6 +247,7 @@ > </span> > </xsl:if> > </span> >+ </xsl:if> > > </xsl:template> > >diff --git a/opac/opac-external-search.pl b/opac/opac-external-search.pl >new file mode 100755 >index 0000000..bbbf2c5 >--- /dev/null >+++ b/opac/opac-external-search.pl >@@ -0,0 +1,63 @@ >+#!/usr/bin/perl >+ >+# Copyright 2009 BibLibre SARL >+# >+# 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 strict; >+use warnings; >+ >+use CGI; >+ >+use C4::Auth qw(:DEFAULT get_session); >+use C4::Output; >+use C4::Search qw( GetExternalSearchTargets ); >+use C4::XSLT qw( XSLTGetFilename ); >+ >+my $cgi = new CGI; >+ >+# Getting the template and auth >+my ($template, $loggedinuser, $cookie) >+= get_template_and_user({template_name => "opac-external-search.tmpl", >+ query => $cgi, >+ type => "opac", >+ authnotrequired => 1, >+ flagsrequired => {borrowers => 1}, >+ debug => 1, >+ }); >+ >+$template->{VARS}->{q} = $cgi->param('q'); >+$template->{VARS}->{limit} = C4::Context->preference('OPACnumSearchResults') || 20; >+$template->{VARS}->{OPACnumSearchResults} = C4::Context->preference('OPACnumSearchResults') || 20; >+$template->{VARS}->{external_search_targets} = GetExternalSearchTargets( C4::Context->userenv ? C4::Context->userenv->{branch} : '' ); >+ >+my @xsltResultStylesheets; >+my @xsltDetailStylesheets; >+ >+foreach my $syntax ( qw( MARC21 UNIMARC NORMARC ) ) { >+ if ( XSLTGetFilename( $syntax, 'OPACXSLTResultsDisplay' ) =~ m,/opac-tmpl/.*|^https:?.*, ) { >+ push @xsltResultStylesheets, { syntax => $syntax, url => $& }; >+ } >+ >+ if ( XSLTGetFilename( $syntax, 'OPACXSLTDetailDisplay' ) =~ m,/opac-tmpl/.*|^https:?.*, ) { >+ push @xsltDetailStylesheets, { syntax => $syntax, url => $& }; >+ } >+} >+ >+$template->{VARS}->{xslt_result_stylesheets} = \@xsltResultStylesheets; >+$template->{VARS}->{xslt_detail_stylesheets} = \@xsltDetailStylesheets; >+ >+output_html_with_http_headers $cgi, $cookie, $template->output; >diff --git a/opac/opac-search.pl b/opac/opac-search.pl >index 2854da6..ccbb72d 100755 >--- a/opac/opac-search.pl >+++ b/opac/opac-search.pl >@@ -74,6 +74,9 @@ if ( $branch_group_limit ) { > -name => 'multibranchlimit', > -values => substr($branch_group_limit, 17) > ); >+ } elsif ( $branch_group_limit eq '@overdrive' ) { >+ print $cgi->redirect( '/cgi-bin/koha/opac-overdrive-search.pl?q=' . join( '+', $cgi->param( 'q' ) ) ); >+ exit; > } else { > $cgi->append( > -name => 'limit', >@@ -887,10 +890,11 @@ $template->{VARS}->{IDreamBooksReviews} = C4::Context->preference('IDreamBooksRe > $template->{VARS}->{IDreamBooksReadometer} = C4::Context->preference('IDreamBooksReadometer'); > $template->{VARS}->{IDreamBooksResults} = C4::Context->preference('IDreamBooksResults'); > >-if ($offset == 0 && IsOverDriveEnabled()) { >- $template->param(OverDriveEnabled => 1); >- $template->param(OverDriveLibraryID => C4::Context->preference('OverDriveLibraryID')); >-} >+$template->{VARS}->{OPACSearchExternalTargets} = C4::Context->preference('OPACSearchExternalTargets'); >+$template->{VARS}->{external_search_targets} = GetExternalSearchTargets( C4::Context->userenv ? C4::Context->userenv->{branch} : '' ); >+ >+$template->{VARS}->{OverDriveLibraryID} = C4::Context->preference('OverDriveLibraryID'); >+$template->{VARS}->{OverDriveEnabled} = ($offset == 0 && IsOverDriveEnabled()); > > $template->param( borrowernumber => $borrowernumber); > output_with_http_headers $cgi, $cookie, $template->output, $content_type; >diff --git a/opac/svc/pazpar2_init b/opac/svc/pazpar2_init >new file mode 100755 >index 0000000..5a0a472 >--- /dev/null >+++ b/opac/svc/pazpar2_init >@@ -0,0 +1,99 @@ >+#!/usr/bin/perl >+ >+# Copyright 2013 ByWater >+# >+# 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. >+ >+=head1 NAME >+ >+svc/pazpar2_init: Initialize a Pazpar2 session >+ >+=head1 SYNOPSIS >+ >+svc/pazpar2_init?targets=3,5,9 -> ../pazpar2/search.pz2?command=init&... >+ >+=head1 DESCRIPTION >+ >+This services connects to pazpar2 and authenticates connections on behalf of >+client-side search code. >+ >+=cut >+ >+use strict; >+use warnings; >+ >+use CGI qw(-oldstyle_urls); >+use HTTP::Request::Common; >+use JSON; >+use URI; >+use XML::Simple; >+ >+use C4::Context; >+use C4::Search; >+use C4::Output; >+ >+my $dbh = C4::Context->dbh; >+my $query = new CGI; >+ >+my %init_opts; >+ >+my $targets = GetExternalSearchTargets( C4::Context->userenv ? C4::Context->userenv->{branch} : '' ); >+ >+foreach my $target ( @$targets ) { >+ my $target_url = $target->{'host'} . ':' . $target->{'port'} . '/' . $target->{'db'}; >+ $init_opts{ 'pz:name[' . $target_url . ']' } = $target->{'name'}; >+ $init_opts{ 'pz:queryencoding[' . $target_url . ']' } = $target->{'encoding'}; >+ $init_opts{ 'pz:xslt[' . $target_url . ']' } = lc( $target->{'syntax'} ) . '-work-groups.xsl'; >+ $init_opts{ 'pz:requestsyntax[' . $target_url . ']' } = $target->{'syntax'}; >+ $init_opts{ 'pz:nativesyntax[' . $target_url . ']' } = 'iso2709'; >+ >+ if ( $target->{'userid'} ) { >+ if ( $target->{'password'} ) { >+ $init_opts{ 'pz:authentication[' . $target_url . ']' } = $target->{'userid'} . '/' . $target->{'password'}; >+ } else { >+ $init_opts{ 'pz:authentication[' . $target_url . ']' } = $target->{'userid'}; >+ } >+ } >+} >+ >+my $uri = 'http://' . C4::Context->preference( 'OPACBaseURL' ) . "/pazpar2/search.pz2"; >+ >+my $request = HTTP::Request::Common::POST( $uri, [ command => 'init', %init_opts ] ); >+ >+my $ua = LWP::UserAgent->new( "Koha " . C4::Context->KOHAVERSION ); >+ >+my $response = $ua->request( $request ) ; >+if ( !$response->is_success ) { >+ print $query->header( >+ -status => '500 Internal Server Error' >+ ); >+ >+ warn "Pazpar2 init failed: " . $response->message; >+ my $content = to_json({ >+ error => 'Could not connect to Pazpar2', >+ }); >+ output_with_http_headers $query, undef, $content, 'json', '500 Internal Server Error'; >+ >+ exit; >+} else { >+ my $xs = XML::Simple->new; >+ my $data = $xs->XMLin( $response->content ); >+ >+ my $content = to_json({ >+ sessionID => $data->{'session'} >+ }); >+ output_with_http_headers $query, undef, $content, 'json', '200 OK'; >+} >diff --git a/rewrite-config.PL b/rewrite-config.PL >index e903d49..1cd7a5a 100644 >--- a/rewrite-config.PL >+++ b/rewrite-config.PL >@@ -137,8 +137,8 @@ $prefix = $ENV{'INSTALL_BASE'} || "/usr"; > "__INSTALL_ZEBRA__" => 'yes', > "__INSTALL_SRU__" => 'yes', > "__INSTALL_PAZPAR2__" => 'no', >- "__PAZPAR2_TOGGLE_XML_PRE__" => '<!--', >- "__PAZPAR2_TOGGLE_XML_POST__" => '-->', >+ "__PAZPAR2_TOGGLE_HTTPD_PRE__" => '<IfDefine PAZPAR2_IS_DISABLED>', >+ "__PAZPAR2_TOGGLE_HTTPD_POST__" => '</IfDefine>', > "__AUTH_INDEX_MODE__" => 'grs1', > "__BIB_INDEX_MODE__" => 'grs1', > "__RUN_DATABASE_TESTS__" => 'no', >@@ -158,8 +158,8 @@ foreach $key (keys %configuration) { > # munge commenting out the PazPar2 mergeserver > # entry in koha-conf.xml if necessary > if ($configuration{'__INSTALL_PAZPAR2__'} eq 'yes') { >- $configuration{'__PAZPAR2_TOGGLE_XML_PRE__'} = ''; >- $configuration{'__PAZPAR2_TOGGLE_XML_POST__'} = ''; >+ $configuration{'__PAZPAR2_TOGGLE_HTTPD_PRE__'} = ''; >+ $configuration{'__PAZPAR2_TOGGLE_HTTPD_POST__'} = ''; > } > > $fname = $ARGV[0]; >-- >1.8.4.rc3
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 10486
:
19142
|
19143
|
19226
|
19227
|
19680
|
21687
|
21734
|
22084
|
22540
|
23109
|
23112
|
23113
|
24036
|
24206
|
24207
|
24208
|
25235
|
25236
|
25979
|
26002
|
26017
|
26129
|
26804
|
26988
|
27275
|
27276
|
27438
|
27439
|
27440
|
27559
|
27756
|
27781
|
27783
|
27785
|
27786
|
27787
|
27788
|
27789
|
27790