Bugzilla – Attachment 91465 Details for
Bug 23173
ILL should be able to search third party sources prior to request creation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 23173: Provide core infrastructure
Bug-23173-Provide-core-infrastructure.patch (text/plain), 33.06 KB, created by
Andrew Isherwood
on 2019-07-11 13:25:03 UTC
(
hide
)
Description:
Bug 23173: Provide core infrastructure
Filename:
MIME Type:
Creator:
Andrew Isherwood
Created:
2019-07-11 13:25:03 UTC
Size:
33.06 KB
patch
obsolete
>From 9f18b67903040cb70099e5d22910f2d760f50683 Mon Sep 17 00:00:00 2001 >From: Andrew Isherwood <andrew.isherwood@ptfs-europe.com> >Date: Thu, 11 Jul 2019 14:15:55 +0100 >Subject: [PATCH] Bug 23173: Provide core infrastructure > >This patch adds the required infrastructure to enable ILL availability >plugins to intercept the request creation process and, using the >supplied metadata, search for and display possible relevant items from >whichever availability plugins are installed. > >Currently two availability plugins exist: > >z39.50 - Searches any number of the Koha instance's configured Z targets >https://github.com/PTFS-Europe/koha-plugin-ill-avail-z3950 > >Unpaywall - Searches the Unpaywall API for possible open access versions >of the requested item >https://github.com/PTFS-Europe/koha-plugin-ill-avail-unpaywall > >The Unpaywall plugin is intended to serve as a "reference" plugin as the >API it deals with is extremely simple >--- > Koha/Illrequest/Availability.pm | 114 ++++++++++++++ > ill/ill-requests.pl | 55 ++++++- > .../intranet-tmpl/prog/css/src/staff-global.scss | 4 + > .../prog/en/includes/ill-availability-table.inc | 17 +++ > .../prog/en/modules/ill/ill-requests.tt | 43 ++++++ > .../prog/en/modules/plugins/plugins-home.tt | 1 + > .../intranet-tmpl/prog/js/ill-availability.js | 161 ++++++++++++++++++++ > koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss | 9 ++ > .../en/includes/ill-availability-table.inc | 17 +++ > .../bootstrap/en/modules/opac-illrequests.tt | 40 +++++ > .../opac-tmpl/bootstrap/js/ill-availability.js | 163 +++++++++++++++++++++ > opac/opac-illrequests.pl | 41 ++++++ > 12 files changed, 659 insertions(+), 6 deletions(-) > create mode 100644 Koha/Illrequest/Availability.pm > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/ill-availability-table.inc > create mode 100644 koha-tmpl/intranet-tmpl/prog/js/ill-availability.js > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/includes/ill-availability-table.inc > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/ill-availability.js > >diff --git a/Koha/Illrequest/Availability.pm b/Koha/Illrequest/Availability.pm >new file mode 100644 >index 0000000000..921e2c9e5f >--- /dev/null >+++ b/Koha/Illrequest/Availability.pm >@@ -0,0 +1,114 @@ >+package Koha::Illrequest::Availability; >+ >+# Copyright 2019 PTFS Europe Ltd >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use JSON; >+use MIME::Base64 qw( encode_base64 ); >+use URI::Escape qw ( uri_escape ); >+ >+use Koha::Plugins; >+ >+=head1 NAME >+ >+Koha::Illrequest::Availability - Koha ILL Availability Searching >+ >+=head1 SYNOPSIS >+ >+Object-oriented class that provides availability searching via >+availability plugins >+ >+=head1 DESCRIPTION >+ >+This class provides the ability to identify and fetch API services >+that can be used to search for item availability >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=head3 new >+ >+ my $availability = Koha::Illrequest::Logger->new($metadata); >+ >+Create a new Koha::Illrequest::Availability object. >+We also store the metadata to be used for searching >+ >+=cut >+ >+sub new { >+ my ( $class, $metadata ) = @_; >+ my $self = {}; >+ >+ $self->{metadata} = $metadata; >+ >+ bless $self, $class; >+ >+ return $self; >+} >+ >+=head3 get_services >+ >+ my $services = Koha::Illrequest::Availability->get_services(); >+ >+Given our metadata, iterate plugins with the right method and >+check if they can service our request and, if so, return an arrayref >+of services >+ >+=cut >+ >+sub get_services { >+ my ( $self ) = @_; >+ >+ my @candidates = Koha::Plugins->new()->GetPlugins({ >+ method => 'ill_availability_services' >+ }); >+ my @services = (); >+ foreach my $plugin(@candidates) { >+ my $valid_service = $plugin->ill_availability_services( >+ $self->{metadata} >+ ); >+ push @services, $valid_service if $valid_service; >+ } >+ >+ return \@services; >+} >+ >+=head3 prep_metadata >+ >+ my $prepared = Koha::Illrequest::Availability->prep_metadata($metadata); >+ >+Given our metadata, return a string representing that metadata that can be >+passed in a URL (encoded in JSON then Base64 encoded) >+ >+=cut >+ >+sub prep_metadata { >+ my ( $self, $metadata ) = @_; >+ >+ return uri_escape(encode_base64(encode_json($metadata))); >+} >+ >+=head1 AUTHOR >+ >+Andrew Isherwood <andrew.isherwood@ptfs-europe.com> >+ >+=cut >+ >+1; >diff --git a/ill/ill-requests.pl b/ill/ill-requests.pl >index 010c61e618..89b342a2f6 100755 >--- a/ill/ill-requests.pl >+++ b/ill/ill-requests.pl >@@ -26,11 +26,13 @@ use C4::Output; > use Koha::AuthorisedValues; > use Koha::Illcomment; > use Koha::Illrequests; >+use Koha::Illrequest::Availability; > use Koha::Libraries; > use Koha::Token; > > use Try::Tiny; > use URI::Escape; >+use JSON; > > our $cgi = CGI->new; > my $illRequests = Koha::Illrequests->new; >@@ -81,12 +83,53 @@ if ( $backends_available ) { > } elsif ( $op eq 'create' ) { > # We're in the process of creating a request > my $request = Koha::Illrequest->new->load_backend( $params->{backend} ); >- my $backend_result = $request->backend_create($params); >- $template->param( >- whole => $backend_result, >- request => $request >- ); >- handle_commit_maybe($backend_result, $request); >+ # Does this backend enable us to insert an availability stage and should >+ # we? If not, proceed as normal. >+ if ( >+ C4::Context->preference("ILLCheckAvailability") && >+ $request->_backend_capability( >+ 'should_display_availability', >+ $params >+ ) && >+ # If the user has elected to continue with the request despite >+ # having viewed availability info, this flag will be set >+ !$params->{checked_availability} >+ ) { >+ # Establish which of the installed availability providers >+ # can service our metadata >+ my $availability = Koha::Illrequest::Availability->new($params); >+ my $services = $availability->get_services(); >+ if (scalar @{$services} > 0) { >+ # Modify our method so we use the correct part of the >+ # template >+ $op = 'availability'; >+ $params->{method} = 'availability'; >+ delete $params->{stage}; >+ # Prepare the metadata we're sending them >+ my $metadata = $availability->prep_metadata($params); >+ $template->param( >+ whole => $params, >+ metadata => $metadata, >+ services_json => scalar encode_json($services), >+ services => $services >+ ); >+ } else { >+ # No services can process this metadata, so continue as normal >+ my $backend_result = $request->backend_create($params); >+ $template->param( >+ whole => $backend_result, >+ request => $request >+ ); >+ handle_commit_maybe($backend_result, $request); >+ } >+ } else { >+ my $backend_result = $request->backend_create($params); >+ $template->param( >+ whole => $backend_result, >+ request => $request >+ ); >+ handle_commit_maybe($backend_result, $request); >+ } > > } elsif ( $op eq 'migrate' ) { > # We're in the process of migrating a request >diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >index e188f00583..0c0781292a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >@@ -4120,6 +4120,10 @@ input.renew { > width: 100% !important; > } > >+.ill_availability_sourcename { >+ margin-top: 20px; >+} >+ > #stockrotation { > h3 { > margin: 30px 0 10px 0; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/ill-availability-table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/ill-availability-table.inc >new file mode 100644 >index 0000000000..3cd00e709d >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/ill-availability-table.inc >@@ -0,0 +1,17 @@ >+<div> >+ <div>[% service.name %]</div> >+ <table class="ill-availability" id="[% service.id %]"> >+ <thead id="[% service.id %]-header"> >+ <tr> >+ <th>Source</th> >+ <th>Title</th> >+ <th>Author</th> >+ <th>ISBN</th> >+ <th>ISSN</th> >+ <th>Date</th> >+ </tr> >+ </thead> >+ <tbody id="[% service.id %]-body"> >+ </tbody> >+ </table> >+</div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt >index 88ee777a09..54340eef40 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/ill/ill-requests.tt >@@ -511,6 +511,40 @@ > [% INCLUDE 'ill-list-table.inc' %] > > </div> >+ [% ELSIF query_type == 'availability' %] >+ <!-- availability --> >+ <h1>Availability</h1> >+ <div id="results"> >+ <h3>Displaying availability results</h3> >+ <form method="POST" action="/cgi-bin/koha/ill/ill-requests.pl"> >+ [% FOREACH key IN whole.keys %] >+ [% value = whole.$key %] >+ [% IF key != 'method' && key != 'custom_key' && key != 'custom_value' %] >+ <input type="hidden" name="[% key | html %]" value="[% value | html %]"> >+ [% END %] >+ [% END %] >+ [% custom_keys = whole.custom_key.split('\0') %] >+ [% custom_values = whole.custom_value.split('\0') %] >+ [% i = 0 %] >+ [% FOREACH custom_key IN custom_keys %] >+ <input type="hidden" name="custom_key" value="[% custom_key %]"> >+ <input type="hidden" name="custom_value" value="[% custom_values.$i %]"> >+ [% i = i + 1 %] >+ [% END %] >+ <input type="hidden" name="method" value="create"> >+ <input type="hidden" name="stage" value="form"> >+ <input type="hidden" name="checked_availability" value="1"> >+ <div id="continue-request-row" class="alert"> >+ If you can't find what you are looking for, you can >+ <button class="button" type="submit">continue creating your request</button> or >+ <a href="/cgi-bin/koha/ill/ill-requests.pl">cancel your request</a> >+ </div> >+ </form> >+ [% FOR service IN services %] >+ <h4 class="ill_availability_sourcename">[% service.plugin %]</h4> >+ [% INCLUDE 'ill-availability-table.inc' service=service %] >+ [% END %] >+ </div> > [% ELSE %] > <!-- Custom Backend Action --> > [% PROCESS $whole.template %] >@@ -530,9 +564,18 @@ > var prefilters = '[% prefilters | $raw %]'; > // Set column settings > var columns_settings = [% ColumnsSettings.GetColumns( 'illrequests', 'ill-requests', 'ill-requests', 'json' ) %]; >+ [% IF services_json.length > 0 %] >+ var services = [% services_json | $raw %]; >+ [% ELSE %] >+ var services = []; >+ [% END %] >+ [% IF metadata.length > 0 %] >+ var metadata = "[% metadata | $raw %]"; >+ [% END %] > </script> > [% INCLUDE 'ill-list-table-strings.inc' %] > [% Asset.js("js/ill-list-table.js") | $raw %] >+ [% Asset.js("js/ill-availability.js") | $raw %] > [% END %] > > [% TRY %] >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt >index 786290bb64..7188669107 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt >@@ -36,6 +36,7 @@ > <li><a href="/cgi-bin/koha/plugins/plugins-home.pl?method=to_marc">View MARC conversion plugins</a></li> > <li><a href="/cgi-bin/koha/plugins/plugins-home.pl?method=opac_online_payment">View online payment plugins</a></li> > <li><a href="/cgi-bin/koha/plugins/plugins-home.pl?method=intranet_catalog_biblio_enhancements">View intranet catalog biblio enhancement plugins</a></li> >+ <li><a href="/cgi-bin/koha/plugins/plugins-home.pl?method=ill_availability_services">View ILL availability plugins</a></li> > </ul> > </div> > </div> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/ill-availability.js b/koha-tmpl/intranet-tmpl/prog/js/ill-availability.js >new file mode 100644 >index 0000000000..14ae748db6 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/js/ill-availability.js >@@ -0,0 +1,161 @@ >+$(document).ready(function() { >+ >+ // In case the source doesn't supply data required for DT to calculate >+ // pagination, we need to do it ourselves >+ var ownPagination = false; >+ var directionSet = false; >+ var start = 0; >+ var forward = true; // true == forward, false == backwards >+ // Arbitrary starting value, it will be corrected by the first >+ // page of results >+ var pageSize = 20; >+ >+ var tableTmpl = { >+ ajax: { >+ cache: true, // Prevent DT appending a "_" cache param >+ }, >+ columns: [ >+ // defaultContent prevents DT from choking if >+ // the API response doesn't return a column >+ { >+ title: 'Source', >+ data: 'source', >+ defaultContent: '' >+ }, >+ { >+ data: 'title', >+ defaultContent: '' >+ }, >+ { >+ data: 'author', >+ defaultContent: '' >+ }, >+ { >+ data: 'isbn', >+ defaultContent: '' >+ }, >+ { >+ data: 'issn', >+ defaultContent: '' >+ }, >+ { >+ data: 'date', >+ defaultContent: '' >+ } >+ ] >+ }; >+ >+ // render functions don't get copied across when we make a dereferenced >+ // copy of them, so we have to reattach them once we have a copy >+ // Here we store them >+ var renders = { >+ title: function(data, type, row) { >+ return row.url ? >+ '<a href="'+row.url+'" target="_blank">'+row.title+'</a>' : >+ row.title; >+ } >+ }; >+ >+ services.forEach(function(service) { >+ // Create a deferenced copy of our table definition object >+ var tableDef = JSON.parse(JSON.stringify(tableTmpl)); >+ // Iterate the table's columns array and add render functions >+ // as necessary >+ tableDef.columns.forEach(function(column) { >+ if (renders[column.data]) { >+ column.render = renders[column.data]; >+ } >+ }); >+ tableDef.ajax.dataSrc = function(data) { >+ var results = data.results.search_results; >+ // The source appears to be returning it's own pagination >+ // data >+ if ( >+ results.hasOwnProperty('recordsFiltered') || >+ results.hasOwnProperty('recordsTotal') >+ ) { >+ return results; >+ } >+ // Set up our own pagination values based on what we just >+ // got back >+ ownPagination = true; >+ directionSet = false; >+ pageSize = results.length; >+ // These values are completely arbitrary, but they enable >+ // us to display pagination links >+ data.recordsFiltered = 5000, >+ data.recordsTotal = 5000; >+ >+ return results; >+ }; >+ tableDef.ajax.data = function(data) { >+ // Datatables sends a bunch of superfluous params >+ // that we don't want to litter our API schema >+ // with, so just remove them from the request >+ if (data.hasOwnProperty('columns')) { >+ delete data.columns; >+ } >+ if (data.hasOwnProperty('draw')) { >+ delete data.draw; >+ } >+ if (data.hasOwnProperty('order')) { >+ delete data.order; >+ } >+ if (data.hasOwnProperty('search')) { >+ delete data.search; >+ } >+ // If we're handling our own pagination, set the properties >+ // that DT will send in the request >+ if (ownPagination) { >+ start = forward ? start + pageSize : start - pageSize; >+ data.start = start; >+ data.length = pageSize; >+ } >+ }; >+ // Add any datatables config options passed from the service >+ // to the table definition >+ tableDef.ajax.url = service.endpoint + metadata; >+ if (service.hasOwnProperty('datatablesConfig')) { >+ var conf = service.datatablesConfig; >+ for (var key in conf) { >+ // The config from the service definition comes from a Perl >+ // hashref, therefore can't contain true/false, so we >+ // special case it >+ if (conf.hasOwnProperty(key)) { >+ if (conf[key] == 'false') { >+ // Special case false values >+ tableDef[key] = false; >+ } else if (conf[key] == 'true') { >+ // Special case true values >+ tableDef[key] = true; >+ } else { >+ // Copy the property value >+ tableDef[key] = conf[key]; >+ } >+ } >+ } >+ } >+ // Create event watchers for the "next" and "previous" pagination >+ // links, this enables us to set the direction the next request is >+ // going in when we're doing our own pagination. We use "hover" >+ // because the click event is caught after the request has been >+ // sent >+ tableDef.drawCallback = function() { >+ $('.paginate_button.next:not(.disabled)', >+ this.api().table().container() >+ ).on('hover', function() { >+ forward = true; >+ directionSet = true; >+ }); >+ $('.paginate_button.previous:not(.disabled)', >+ this.api().table().container() >+ ).on('hover', function() { >+ forward = false; >+ directionSet = true; >+ }); >+ } >+ // Initialise the table >+ KohaTable(service.id, tableDef); >+ }); >+ >+}); >diff --git a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss b/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss >index 1e389c2ab9..91d4bbf2aa 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss >+++ b/koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss >@@ -3030,6 +3030,15 @@ button.closebtn { > .dropdown:hover .dropdown-menu.nojs { > display: block; > } >+ >+} >+ >+.ill_availability_sourcename { >+ margin-top: 20px; >+} >+ >+#continue-request-row { >+ text-align: center; > } > > #dc_fieldset { >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/ill-availability-table.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/ill-availability-table.inc >new file mode 100644 >index 0000000000..a2597bc3cf >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/ill-availability-table.inc >@@ -0,0 +1,17 @@ >+<div> >+ <div>[% service.name %]</div> >+ <table class="ill-availability table table-bordered table-striped" id="[% service.id %]"> >+ <thead id="[% service.id %]-header"> >+ <tr> >+ <th>Source</th> >+ <th>Title</th> >+ <th>Author</th> >+ <th>ISBN</th> >+ <th>ISSN</th> >+ <th>Date</th> >+ </tr> >+ </thead> >+ <tbody id="[% service.id %]-body"> >+ </tbody> >+ </table> >+</div> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt >index 218a6e2aa2..58c0a0dddd 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-illrequests.tt >@@ -224,6 +224,37 @@ > <span class="cancel"><a href="/cgi-bin/koha/opac-illrequests.pl">Cancel</a></span> > </fieldset> > </form> >+ [% ELSIF method == 'availability' %] >+ <h2>Interlibrary loan item availability</h2> >+ <div id="results"> >+ <h3>Displaying availability results</h3> >+ <form method="POST" action="/cgi-bin/koha/opac-illrequests.pl"> >+ [% FOREACH key IN whole.keys %] >+ [% value = whole.$key %] >+ [% IF key != 'custom_key' && key != 'custom_value' %] >+ <input type="hidden" name="[% key | html %]" value="[% value | html %]"> >+ [% END %] >+ [% END %] >+ [% custom_keys = whole.custom_key.split('\0') %] >+ [% custom_values = whole.custom_value.split('\0') %] >+ [% i = 0 %] >+ [% FOREACH custom_key IN custom_keys %] >+ <input type="hidden" name="custom_key" value="[% custom_key %]"> >+ <input type="hidden" name="custom_value" value="[% custom_values.$i %]"> >+ [% i = i + 1 %] >+ [% END %] >+ <input type="hidden" name="checked_availability" value="1"> >+ <div id="continue-request-row" class="alert"> >+ If you can't find what you are looking for, you can >+ <button class="button" type="submit">continue creating your request</button> or >+ <a href="/cgi-bin/koha/opac-illrequests.pl">cancel your request</a> >+ </div> >+ </form> >+ [% FOR service IN services %] >+ <h4 class="ill_availability_sourcename">[% service.plugin %]</h4> >+ [% INCLUDE 'ill-availability-table.inc' service=service %] >+ [% END %] >+ </div> > [% END %] > </div> <!-- / .maincontent --> > [% END %] >@@ -247,8 +278,17 @@ > "deferRender": true > })); > $("#backend-dropdown-options").removeClass("nojs"); >+ [% IF services_json.length > 0 %] >+ var services = [% services_json | $raw %]; >+ [% ELSE %] >+ var services = []; >+ [% END %] >+ [% IF metadata.length > 0 %] >+ var metadata = "[% metadata | $raw %]"; >+ [% END %] > //]]> > </script> >+[% Asset.js("js/ill-availability.js") | $raw %] > [% TRY %] > [% PROCESS backend_jsinclude %] > [% CATCH %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/ill-availability.js b/koha-tmpl/opac-tmpl/bootstrap/js/ill-availability.js >new file mode 100644 >index 0000000000..1f1e5a848b >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/js/ill-availability.js >@@ -0,0 +1,163 @@ >+$(document).ready(function() { >+ >+ // In case the source doesn't supply data required for DT to calculate >+ // pagination, we need to do it ourselves >+ var ownPagination = false; >+ var directionSet = false; >+ var start = 0; >+ var forward = true; // true == forward, false == backwards >+ // Arbitrary starting value, it will be corrected by the first >+ // page of results >+ var pageSize = 20; >+ >+ var tableTmpl = { >+ ajax: { >+ cache: true, // Prevent DT appending a "_" cache param >+ }, >+ columns: [ >+ // defaultContent prevents DT from choking if >+ // the API response doesn't return a column >+ { >+ title: 'Source', >+ data: 'source', >+ defaultContent: '' >+ }, >+ { >+ data: 'title', >+ defaultContent: '' >+ }, >+ { >+ data: 'author', >+ defaultContent: '' >+ }, >+ { >+ data: 'isbn', >+ defaultContent: '' >+ }, >+ { >+ data: 'issn', >+ defaultContent: '' >+ }, >+ { >+ data: 'date', >+ defaultContent: '' >+ } >+ ] >+ }; >+ >+ // render functions don't get copied across when we make a dereferenced >+ // copy of them, so we have to reattach them once we have a copy >+ // Here we store them >+ var renders = { >+ title: function(data, type, row) { >+ return row.url ? >+ '<a href="'+row.url+'" target="_blank">'+row.title+'</a>' : >+ row.title; >+ } >+ }; >+ >+ services.forEach(function(service) { >+ // Create a deferenced copy of our table definition object >+ var tableDef = JSON.parse(JSON.stringify(tableTmpl)); >+ // Iterate the table's columns array and add render functions >+ // as necessary >+ tableDef.columns.forEach(function(column) { >+ if (renders[column.data]) { >+ column.render = renders[column.data]; >+ } >+ }); >+ tableDef.ajax.dataSrc = function(data) { >+ var results = data.results.search_results; >+ // The source appears to be returning it's own pagination >+ // data >+ if ( >+ results.hasOwnProperty('recordsFiltered') || >+ results.hasOwnProperty('recordsTotal') >+ ) { >+ return results; >+ } >+ // Set up our own pagination values based on what we just >+ // got back >+ ownPagination = true; >+ directionSet = false; >+ pageSize = results.length; >+ // These values are completely arbitrary, but they enable >+ // us to display pagination links >+ data.recordsFiltered = 5000, >+ data.recordsTotal = 5000; >+ >+ return results; >+ }; >+ tableDef.ajax.data = function(data) { >+ // Datatables sends a bunch of superfluous params >+ // that we don't want to litter our API schema >+ // with, so just remove them from the request >+ if (data.hasOwnProperty('columns')) { >+ delete data.columns; >+ } >+ if (data.hasOwnProperty('draw')) { >+ delete data.draw; >+ } >+ if (data.hasOwnProperty('order')) { >+ delete data.order; >+ } >+ if (data.hasOwnProperty('search')) { >+ delete data.search; >+ } >+ // If we're handling our own pagination, set the properties >+ // that DT will send in the request >+ if (ownPagination) { >+ start = forward ? start + pageSize : start - pageSize; >+ data.start = start; >+ data.length = pageSize; >+ } >+ }; >+ // Add any datatables config options passed from the service >+ // to the table definition >+ tableDef.ajax.url = service.endpoint + metadata; >+ if (service.hasOwnProperty('datatablesConfig')) { >+ var conf = service.datatablesConfig; >+ for (var key in conf) { >+ // The config from the service definition comes from a Perl >+ // hashref, therefore can't contain true/false, so we >+ // special case it >+ if (conf.hasOwnProperty(key)) { >+ if (conf[key] == 'false') { >+ // Special case false values >+ tableDef[key] = false; >+ } else if (conf[key] == 'true') { >+ // Special case true values >+ tableDef[key] = true; >+ } else { >+ // Copy the property value >+ tableDef[key] = conf[key]; >+ } >+ } >+ } >+ } >+ // Create event watchers for the "next" and "previous" pagination >+ // links, this enables us to set the direction the next request is >+ // going in when we're doing our own pagination. We use "hover" >+ // because the click event is caught after the request has been >+ // sent >+ tableDef.drawCallback = function() { >+ $('.paginate_button.next:not(.disabled)', >+ this.api().table().container() >+ ).on('hover', function() { >+ forward = true; >+ directionSet = true; >+ }); >+ $('.paginate_button.previous:not(.disabled)', >+ this.api().table().container() >+ ).on('hover', function() { >+ forward = false; >+ directionSet = true; >+ }); >+ } >+ // Initialise the table >+ $('#'+service.id ).dataTable( >+ $.extend(true, {}, dataTablesDefaults, tableDef) >+ ); >+ }); >+ >+}); >diff --git a/opac/opac-illrequests.pl b/opac/opac-illrequests.pl >index f35b19ada9..3ceffc8460 100755 >--- a/opac/opac-illrequests.pl >+++ b/opac/opac-illrequests.pl >@@ -19,6 +19,8 @@ > > use Modern::Perl; > >+use JSON qw( encode_json ); >+ > use CGI qw ( -utf8 ); > use C4::Auth; > use C4::Koha; >@@ -28,6 +30,7 @@ use Koha::Illrequest::Config; > use Koha::Illrequests; > use Koha::Libraries; > use Koha::Patrons; >+use Koha::Illrequest::Availability; > > my $query = new CGI; > >@@ -110,6 +113,44 @@ if ( $op eq 'list' ) { > } else { > my $request = Koha::Illrequest->new > ->load_backend($params->{backend}); >+ >+ # Does this backend enable us to insert an availability stage and should >+ # we? If not, proceed as normal. >+ if ( >+ C4::Context->preference("ILLCheckAvailability") && >+ $request->_backend_capability( >+ 'should_display_availability', >+ $params >+ ) && >+ # If the user has elected to continue with the request despite >+ # having viewed availability info, this flag will be set >+ !$params->{checked_availability} >+ ) { >+ # Establish which of the installed availability providers >+ # can service our metadata, if so, jump in >+ my $availability = Koha::Illrequest::Availability->new($params); >+ my $services = $availability->get_services(); >+ if (scalar @{$services} > 0) { >+ # Modify our method so we use the correct part of the >+ # template >+ $op = 'availability'; >+ # Prepare the metadata we're sending them >+ my $metadata = $availability->prep_metadata($params); >+ $template->param( >+ metadata => $metadata, >+ services_json => encode_json($services), >+ services => $services, >+ illrequestsview => 1, >+ message => $params->{message}, >+ method => $op, >+ whole => $params >+ ); >+ output_html_with_http_headers $query, $cookie, >+ $template->output, undef, { force_no_caching => 1 }; >+ exit; >+ } >+ } >+ > $params->{cardnumber} = Koha::Patrons->find({ > borrowernumber => $loggedinuser > })->cardnumber; >-- >2.11.0
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 23173
:
91464
|
91465
|
92107
|
92108
|
92539
|
92540
|
92550
|
92551
|
92640
|
92641
|
92693
|
92694
|
92695
|
92715
|
92716
|
92717
|
93146
|
93147
|
93148
|
93909
|
93910
|
93911
|
95268
|
95269
|
95270
|
98521
|
99083
|
100724
|
100725
|
100740
|
102179
|
102180
|
102181
|
102182
|
102183
|
102184
|
102286
|
102287
|
102288
|
102289
|
102290
|
102291
|
102292
|
102293
|
102294