Bugzilla – Attachment 76182 Details for
Bug 17602
Integrate support for RecordedBooks (formerly OneClickDigital) API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 17602: OPAC integration of RecordedBooks
Bug-17602-OPAC-integration-of-RecordedBooks.patch (text/plain), 33.67 KB, created by
Jonathan Druart
on 2018-06-19 18:55:41 UTC
(
hide
)
Description:
Bug 17602: OPAC integration of RecordedBooks
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2018-06-19 18:55:41 UTC
Size:
33.67 KB
patch
obsolete
>From ca7309c3aba95cbc9667472c5fa33fb3af376864 Mon Sep 17 00:00:00 2001 >From: Srdjan <srdjan@catalyst.net.nz> >Date: Fri, 23 Sep 2016 18:13:10 +1200 >Subject: [PATCH] Bug 17602: OPAC integration of RecordedBooks > >Add RecordedBooks to the users page in the public interface > >To Test: >1/ Apply all 3 patches >2/ Set the sysprefs to valid values (you will need a test account with RecordedBooks) >3/ Try a search >4/ Login to the OPAC, try to place a hold, or check an item out >5/ Check the opac-user page, see if your items are showing on the oneclickdigital tab > >Signed-off-by: Nick Clemens <nick@bywatersolutions.com> >Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> >--- > .../en/includes/recordedbooks-checkout.inc | 15 + > .../en/modules/opac-recordedbooks-search.tt | 168 +++++++++++ > .../opac-tmpl/bootstrap/en/modules/opac-results.tt | 18 ++ > .../opac-tmpl/bootstrap/en/modules/opac-user.tt | 24 ++ > koha-tmpl/opac-tmpl/bootstrap/js/recordedbooks.js | 325 +++++++++++++++++++++ > koha-tmpl/opac-tmpl/bootstrap/less/opac.less | 2 +- > opac/opac-recordedbooks-search.pl | 42 +++ > opac/opac-search.pl | 9 +- > opac/opac-user.pl | 1 + > opac/svc/recordedbooks | 148 ++++++++++ > 10 files changed, 748 insertions(+), 4 deletions(-) > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/includes/recordedbooks-checkout.inc > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-recordedbooks-search.tt > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/js/recordedbooks.js > create mode 100755 opac/opac-recordedbooks-search.pl > create mode 100755 opac/svc/recordedbooks > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/recordedbooks-checkout.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/recordedbooks-checkout.inc >new file mode 100644 >index 0000000000..bebf3d48fa >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/recordedbooks-checkout.inc >@@ -0,0 +1,15 @@ >+<div id="recordedbooks-checkout" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="recordedbooks-checkout-label" aria-hidden="true"> >+ <div class="modal-header"> >+ <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ã</button> >+ <h3 id="recordedbooks-checkout-label">Checkout</h3> >+ </div> >+ <form action="#" method="post" id="recordedbooks-checkout-form"> >+ <div class="modal-body"> >+ <input type="hidden" name="id" value="" /> >+ </div> >+ <div class="modal-footer"> >+ <input type="submit" class="btn btn-primary recordedbooks-checkout-submit" value="Checkout" /> >+ <a href="#" data-dismiss="modal" aria-hidden="true" class="cancel">Cancel</a> >+ </div> >+ </form> <!-- /#recordedbooks-checkout-form --> >+</div> <!-- /#recordedbooks-checkout --> >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-recordedbooks-search.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-recordedbooks-search.tt >new file mode 100644 >index 0000000000..b90f6ac180 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-recordedbooks-search.tt >@@ -0,0 +1,168 @@ >+[% USE Koha %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › RecordedBooks search for '[% q | html %]'</title> >+[% INCLUDE 'doc-head-close.inc' %] >+[% BLOCK cssinclude %] >+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/jquery.rating.css" /> >+<style> >+.actions a.addtocart { >+ display: inline; >+} >+</style> >+[% END %] >+</head> >+[% INCLUDE 'bodytag.inc' bodyid='recordedbooks-results-page' bodyclass='scrollto' %] >+[% INCLUDE 'masthead.inc' %] >+ >+ <div class="main"> >+ <ul class="breadcrumb"> >+ <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">›</span></li> >+ <li><a href="#">RecordedBooks search for '[% q | html %]'</a></li> >+ </ul> >+ >+ <div class="container-fluid"> >+ <div class="row-fluid"> >+ <div class="span2"> >+ [% IF ( OpacNav || OpacNavBottom ) %] >+ [% INCLUDE 'navigation.inc' %] >+ [% END %] >+ </div> >+ <div class="span10"> >+ <div id="recordedbooks-results-content" class="maincontent searchresults"> >+ <h1>RecordedBooks search for '[% q | html %]'</h1> >+ <div id="breadcrumbs"> >+ <p></p> >+ </div> >+ >+ <div id="top-pages"> >+ <div class="pagination pagination-small"> >+ </div> >+ </div> >+ >+ <table id="recordedbooks-results-list" class="table table-striped"> >+ <tbody> >+ </tbody> >+ </table> >+ >+ <div id="bottom-pages"> >+ <div class="pagination pagination-small"> >+ </div> >+ </div> >+ >+ </div> <!-- / #recordedbooks-results-content --> >+ </div> <!-- / .span10 --> >+ </div> <!-- / .row-fluid --> >+ </div> <!-- / .container-fluid --> >+ </div> <!-- / .main --> >+ >+[% INCLUDE 'recordedbooks-checkout.inc' %] >+ >+[% INCLUDE 'opac-bottom.inc' %] >+[% BLOCK jsinclude %] >+<script type="text/javascript" src="[% interface %]/[% theme %]/js/recordedbooks.js"></script> >+<script type="text/javascript" src="[% interface %]/[% theme %]/lib/jquery/plugins/jquery.rating.js"></script> >+<script type="text/javascript"> >+var querystring = "[% q |replace( "'", "\'" ) |replace( '\n', '\\n' ) |replace( '\r', '\\r' ) |html %]"; >+var results_per_page = [% OPACnumSearchResults || 20 %]; >+ >+function search( page ) { >+ $( '#recordedbooks-status' ).html( _("Searching RecordedBooks...") + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></span>' ); >+ >+ KOHA.RecordedBooks.search( querystring, results_per_page, page, function( data ) { >+ if ( data.error ) { >+ $( '#recordedbooks-status' ).html( '<strong class="unavailable">' + _("Error searching RecordedBooks collection") + ': ' + data.error + '</strong>' ); >+ return; >+ } >+ >+ if ( !data.total ) { >+ $( '#recordedbooks-status' ).html( '<strong>' + _("No results found in the library's RecordedBooks collection.") + '</strong>' ); >+ return; >+ } >+ >+ $( '#recordedbooks-results-list tbody' ).empty(); >+ >+ $( '#recordedbooks-status' ).html( '<strong>' + _("Found") + ' ' + data.total + ' ' + _("results in the library's RecordedBooks collection.") + '</strong>' ); >+ >+ for ( var i = 0; data.items[i]; i++ ) { >+ var prod = data.items[i]; >+ var results = []; >+ >+ results.push( '<tr>' ); >+ >+ results.push( '<td class="info"><span class="title">' ); >+ if (prod.url) results.push( '<a href="', prod.url, '" target="recordedbooks">' ); >+ results.push( prod.title ); >+ if (prod.url) results.push( '</a>' ); >+ results.push( '</span>' ); >+ results.push( '<p>' + _("by") + ' ', prod.author, '</p>' ); >+ if (prod.description) results.push( '<p>' + prod.description, '</p>' ); >+ results.push( '<span class="results_summary mediatype"><span class="label">' + _("Type:") + ' </span>', prod.media, '</span>' ); >+ >+ results.push( '</td>' ); >+ >+ results.push( '<td>' ); >+ if ( prod.images && prod.images.medium ) { >+ if (prod.url) results.push( '<a href="', prod.url, '" target="recordedbooks">' ); >+ results.push( '<img class="thumbnail" src="', prod.images.medium, '" />' ); >+ if (prod.url) results.push( '</a>' ); >+ } >+ results.push( '</td>' ); >+ >+ results.push( '</tr>' ); >+ var $tr = $( results.join( '' )); >+ $( '#recordedbooks-results-list tbody' ).append( $tr ); >+ >+ $tr.find( '.info' ).each(function() { >+ KOHA.RecordedBooks.add_actions(this, prod.isbn); >+ }); >+ } >+ >+ $( '#recordedbooks-results-list tr:odd' ).addClass( 'highlight' ); >+ >+ var pages = []; >+ >+ var max_page = Math.floor( data.total / results_per_page ); >+ if (data.total == page*results_per_page) max_page++; >+ >+ if ( page != 1 ) { >+ pages.push( '<li><a class="od-nav" href="#" data-page="' + (page - 1) + '">« ' + _("Previous") + '</a></li>' ); >+ } >+ >+ for ( var p = Math.max( 0, page - 9 ); p <= Math.min( max_page, p + 9 ); p++ ) { >+ if ( p == page ) { >+ pages.push( ' <li class="active"><a href="#">' + ( p + 1 ) + '</a></li>' ); >+ } else { >+ pages.push( ' <li><a class="od-nav" href="#" data-page="' + p + '">' + p + '</a></li>' ); >+ } >+ } >+ >+ if ( page < max_page ) { >+ pages.push( ' <li><a class="od-nav" href="#" data-page="' + (page + 1) + '">' + _("Next") + ' »</a></li>' ); >+ } >+ >+ if ( pages.length > 1 ) $( '#top-pages, #bottom-pages' ).find( '.pagination' ).html( '<ul>' + pages.join( '' ) + '</ul>'); >+ >+ $( '#recordedbooks-results-list input.star' ).rating(); >+ } ); >+} >+ >+$( document ).ready( function() { >+ $( '#breadcrumbs p' ) >+ .append( ' ' ) >+ .append( '<span id="recordedbooks-status"></span>' ); >+ >+ $( document ).on( 'click', 'a.od-nav', function() { >+ search( $( this ).data( 'page' ) ); >+ return false; >+ }); >+ >+ [% IF ( loggedinusername ) %] >+ KOHA.RecordedBooks.with_account_details("#breadcrumbs", function() { >+ search( 1 ); >+ }); >+ [% ELSE %] >+ search( 1 ); >+ [% END %] >+} ); >+</script> >+[% END %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt >index c30f330a4e..4ea5ad3baa 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt >@@ -593,6 +593,7 @@ > [% END %] > [% IF ( OpacStarRatings == 'all' || Koha.Preference('Babeltheque') ) %][% Asset.js("lib/jquery/plugins/jquery.rating.js") %][% END %] > [% IF ( OverDriveEnabled ) %][% Asset.js("js/overdrive.js") %][% END %] >+[% IF ( RecordedBooksEnabled ) %][% Asset.js("js/recordedbooks.js") %][% END %] > [% Asset.js("lib/jquery/plugins/jquery.checkboxes.min.js") %] > [% IF ( OpacHighlightedWords ) %][% Asset.js("lib/jquery/plugins/jquery.highlight-3.js") %] > [% END %]<script> >@@ -904,6 +905,23 @@ $(document).ready(function(){ > } > } ); > [% END %] >+ [% IF ( RecordedBooksEnabled ) %] >+ var $recordedbooks_results = $( '<div id="recordedbooks-results">' + _( 'Searching RecordedBooks...' ) + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></div>' ); >+ $( '#numresults' ) .append( ' ' ) >+ .append( $recordedbooks_results ); >+ KOHA.RecordedBooks.search( querystring, [% OPACnumSearchResults || "null" %], null, function( data ) { >+ if ( data.error ) { >+ $recordedbooks_results.html( _( 'Error searching RecordedBooks collection' ) + ': ' + data.error); >+ return; >+ } >+ >+ if ( data.total > 0 ) { >+ $recordedbooks_results.html( _( 'Found' ) + ' <a href="/cgi-bin/koha/opac-recordedbooks-search.pl?q=' + escape( querystring ) + '">' + data.total + ' ' + _( 'results' ) + '</a> ' + _( 'in RecordedBooks collection' ) ); >+ } else { >+ $recordedbooks_results.remove(); >+ } >+ } ); >+ [% END %] > [% IF ( OpenLibrarySearch ) %] > var $openlibrary_results = $( '<div id="openlibrary-results">' + _( 'Searching Open Library...' ) + ' <img class="throbber" src="[% interface %]/lib/jquery/plugins/themes/classic/throbber.gif" /></div>' ); > $( '#numresults' ) .append( ' ' ) >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >index 85680afd4b..631bcf04f8 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >@@ -148,10 +148,15 @@ > [% IF ( OverDriveCirculation ) %] > <li><a href="#opac-user-overdrive">OverDrive Account</a></li> > [% END %] >+ [% IF ( RecordedBooksCirculation ) %] >+ <li><a href="#opac-user-recordedbooks">RecordedBooks Account</a></li> >+ [% END %] > </ul> > > <div id="opac-user-overdrive"> > </div> >+ <div id="opac-user-recordedbooks"> >+ </div> > <div id="opac-user-checkouts"> > [% IF ( issues_count ) %] > <form id="renewselected" action="/cgi-bin/koha/opac-renew.pl" method="post"> >@@ -878,6 +883,9 @@ > [% IF ( OverDriveCirculation ) %] > [% INCLUDE 'overdrive-checkout.inc' %] > [% END %] >+[% IF ( RecordedBooksCirculation ) %] >+[% INCLUDE 'recordedbooks-checkout.inc' %] >+[% END %] > > [% INCLUDE 'opac-bottom.inc' %] > >@@ -1050,4 +1058,20 @@ > }); > </script> > [% END %] >+ [% IF RecordedBooksCirculation %] >+ <script type="text/javascript" src="[% interface %]//[% theme %]/js/recordedbooks.js"></script> >+ <script type="text/JavaScript"> >+ $(document).ready(function() { >+ [% IF ( recordedbooks_error ) %] >+ KOHA.RecordedBooks.display_error("#opac-user-recordedbooks", "[% recordedbooks_error.dquote %]"); >+ [% END %] >+ [% IF ( recordedbooks_tab ) %] >+ $("#opac-user-views").tabs("select", "#opac-user-recordedbooks"); >+ [% END %] >+ $("#opac-user-recordedbooks").each( function() { >+ KOHA.RecordedBooks.display_account_details(this); >+ } ); >+ }); >+ [% END %] >+ </script> > [% END %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/recordedbooks.js b/koha-tmpl/opac-tmpl/bootstrap/js/recordedbooks.js >new file mode 100644 >index 0000000000..5df3f3a2e9 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/js/recordedbooks.js >@@ -0,0 +1,325 @@ >+if ( typeof KOHA == "undefined" || !KOHA ) { >+ var KOHA = {}; >+} >+ >+KOHA.RecordedBooks = new function() { >+ var svc_url = '/cgi-bin/koha/svc/recordedbooks'; >+ >+ var error_div = $('<div class="recordedbooks-error">'); >+ function display_error ( error ) { >+ error_div.text(error); >+ } >+ >+ var details = null; >+ >+ function is_identified() { >+ return details ? details.is_identified : false; >+ } >+ >+ var checkout_popup = null; >+ $( document ).ready(function() { >+ checkout_popup = $("#recordedbooks-checkout"); >+ }); >+ >+ function display_account (container, data) { >+ if (!data.is_identified) { >+ return; >+ } >+ >+ if (data.checkouts) { >+ var checkouts_div = $('<div class="recordedbooks-div">').html('<h3>' + _("Checkouts") + '</h3>'); >+ var items = data.checkouts.items; >+ var checkouts_list; >+ if (items.length == 0) { >+ checkouts_list = _("No checkouts"); >+ } else { >+ checkouts_list = $('<ul class="recordedbooks-list">'); >+ data.checkouts.items.forEach(function(item) { >+ item_line(checkouts_list, item); >+ }); >+ } >+ checkouts_div.append(checkouts_list); >+ $(container).append(checkouts_div); >+ } >+ >+ if (data.holds) { >+ var holds_div = $('<div class="recordedbooks-div">').html('<h3>' + _("Holds") + '</h3>'); >+ var items = data.holds.items; >+ var holds_list; >+ if (items.length == 0) { >+ holds_list = _("No holds"); >+ } else { >+ holds_list = $('<ul class="recordedbooks-list">'); >+ data.holds.items.forEach(function(item) { >+ item_line(holds_list, item); >+ }); >+ } >+ holds_div.append(holds_list); >+ $(container).append(holds_div); >+ } >+ } >+ >+ function item_line(ul_el, item) { >+ var line = $('<li class="recordedbooks-item">'); >+ if (item.images) { >+ var thumb_url = item.images.small; >+ if (thumb_url) { >+ $('<img class="recordedbooks-item-thumbnail">') >+ .attr("src", thumb_url) >+ .appendTo(line); >+ } >+ } >+ $('<div class="recordedbooks-item-title">') >+ .text(item.title) >+ .appendTo(line); >+ $('<div class="recordedbooks-item-subtitle">') >+ .text(item.subtitle) >+ .appendTo(line); >+ $('<div class="recordedbooks-item-author">') >+ .text(item.author) >+ .appendTo(line); >+ if (item.files && item.files.length > 0) { >+ downloads = $('<div class="recordedbooks-item-author">') >+ .text("Downloads") >+ .appendTo(line); >+ render_downloads(downloads, item.files); >+ } >+ var actions = $('<span class="actions">'); >+ display_actions(actions, item.isbn); >+ $('<div id="action_'+item.isbn+'" class="actions-menu">') >+ .append(actions) >+ .appendTo(line); >+ >+ $(ul_el).append(line); >+ } >+ >+ function render_downloads(el, files) { >+ if (files.length == 0) return; >+ var file_spec = files.shift(); >+ if (/^https?:\/\/api\./.test(file_spec.url)) { >+ $.ajax({ >+ dataType: "json", >+ url: file_spec.url, >+ success: function (data) { >+ append_download_link(el, data.url, data.id); >+ render_downloads(el, files); >+ }, >+ error: function(jqXHR, textStatus, errorThrown) { >+ display_error(errorThrown); >+ } >+ }); >+ } else { >+ append_download_link(el, file_spec.url, file_spec.filename); >+ render_downloads(el, files); >+ } >+ } >+ function append_download_link(el, url, text) { >+ var p = $("<p>"); >+ $( '<a href="' + url + '" target="recordedbooks">' ) >+ .text(text) >+ .appendTo(p); >+ el.append(p); >+ } >+ >+ function svc_ajax ( method, params, success_callback, callback_for_error_too ) { >+ // remove when jquery is upgraded >+ for (var key in params) { >+ if (params[key] === null) delete params[key]; >+ } >+ return $.ajax({ >+ method: method, >+ dataType: "json", >+ url: svc_url, >+ data: params, >+ success: function (data) { >+ if (data.error && !callback_for_error_too) { >+ display_error(data.error); >+ } >+ success_callback(data); >+ }, >+ error: function(jqXHR, textStatus, errorThrown) { >+ if (callback_for_error_too) { >+ success_callback({error: errorThrown}); >+ return; >+ } >+ display_error(errorThrown); >+ } >+ }); >+ } >+ >+ function load_account_details ( callback ) { >+ svc_ajax('get', { action: "account" }, function(data) { >+ details = data; >+ callback(data); >+ }); >+ } >+ >+ function item_action (params, el) { >+ var isbn = params.isbn; >+ svc_ajax('post', params, function(data) { >+ if (data.checkouts) { >+ details.checkouts = data.checkouts; >+ } >+ if (data.holds) { >+ details.holds = data.holds; >+ } >+ display_actions(el, isbn); >+ }); >+ } >+ >+ function item_is_checked_out (isbn) { >+ if ( !(details && details.checkouts) ) { >+ return null; >+ } >+ var isbn_uc = isbn.toUpperCase(); >+ var items = details.checkouts.items; >+ for (var i = 0; i < items.length; i++) { >+ if ( items[i].isbn.toUpperCase() == isbn_uc ) { >+ return items[i]; >+ } >+ } >+ return null; >+ } >+ >+ function item_is_on_hold (isbn) { >+ if ( !(details && details.holds) ) { >+ return false; >+ } >+ var isbn_uc = isbn.toUpperCase(); >+ var items = details.holds.items; >+ for (var i = 0; i < items.length; i++) { >+ if ( items[i].isbn.toUpperCase() == isbn_uc ) { >+ return items[i]; >+ } >+ } >+ return null; >+ } >+ >+ function display_actions(el, isbn) { >+ $(el).empty(); >+ if (is_identified()) { >+ >+ var item = item_is_checked_out(isbn); >+ if (item) { >+ var expires = new Date(item.expires); >+ $('<span class="recordedbooks-item-status">') >+ .text(_("Checked out until") + " " + expires.toLocaleString()) >+ .appendTo(el); >+ $(el).append(" "); >+ >+ if (item.url) { >+ var download = $('<a href="'+item.url+'">').appendTo(el); >+ decorate_button(download, _("Download")); >+ $(el).append(" "); >+ } >+ >+ $(el).append( ajax_button(_("Check in"), function() { >+ if( confirm(_("Are you sure you want to return this item?")) ) { >+ item_action({action: "return", isbn: isbn}, el); >+ } >+ }) ); >+ >+ return item; >+ } >+ >+ item = item_is_on_hold(isbn); >+ if (item) { >+ $('<span class="recordedbooks-status">') >+ .text(_("On hold")) >+ .appendTo(el); >+ $(el).append(" "); >+ } >+ >+ if(checkout_popup) { >+ $(el).append( ajax_button(_("Check out"), function() { >+ if( confirm(_("Are you sure you want to checkout this item?")) ) { >+ svc_ajax('post', {action: "checkout", isbn: isbn}, function(data) { >+ if (data.checkouts) { >+ details.checkouts = data.checkouts; >+ } >+ if (data.holds) { >+ details.holds = data.holds; >+ } >+ item = display_actions(el, isbn); >+ }); >+ } >+ }) ); >+ } >+ if (!item) { >+ $(el).append( ajax_button(_("Place hold"), function() { >+ item_action({action: "place_hold", isbn: isbn}, el); >+ }) ); >+ } >+ >+ if (item) { >+ $(el).append( ajax_button(_("Cancel"), function() { >+ if( confirm(_("Are you sure you want to cancel this hold?")) ) { >+ item_action({action: "remove_hold", isbn: isbn}, el); >+ } >+ }) ); >+ } >+ return item; >+ } >+ } >+ >+ function ajax_button(label, on_click) { >+ var button = $('<a href="#">') >+ .click(function(e) { >+ e.preventDefault(); >+ on_click(); >+ }); >+ decorate_button(button, label); >+ return button; >+ } >+ >+ function decorate_button(button, label) { >+ $(button) >+ .addClass("btn btn-primary btn-mini") >+ .css("color","white") >+ .text(label); >+ } >+ >+ this.with_account_details = function( el, callback ) { >+ $(el).append(error_div); >+ load_account_details( callback ); >+ } >+ >+ this.display_account_details = function( el ) { >+ $(el).empty().append(error_div); >+ load_account_details(function(data) { >+ display_account(el, data); >+ }); >+ }; >+ >+ this.display_error = function( el, error ) { >+ $(el).empty().append(error_div); >+ display_error(error); >+ }; >+ >+ this.is_identified = is_identified; >+ >+ this.add_actions = function(el, isbn) { >+ var actions = $('<span class="actions">'); >+ display_actions(actions, isbn); >+ $('<div id="action_'+isbn+'" class="actions-menu">') >+ .append(actions) >+ .appendTo(el); >+ }; >+ >+ this.search = function( q, page_size, page, callback ) { >+ svc_ajax('get', { action: "search", q: q, page_size: page_size, page: page }, function (data) { >+ var results; >+ if (data.results) { >+ results = data.results; >+ if (!results.total) { >+ var total = results.items.length; >+ if ( total == results.page_size ) total = total + "+"; >+ results.total = total; >+ } >+ } >+ else results = {}; >+ results.error = data.error; >+ callback(results); >+ }, true); >+ }; >+} >diff --git a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less b/koha-tmpl/opac-tmpl/bootstrap/less/opac.less >index 88b350a638..900c2a0415 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/less/opac.less >+++ b/koha-tmpl/opac-tmpl/bootstrap/less/opac.less >@@ -2308,7 +2308,7 @@ td img { > } > > >-#overdrive-results, #openlibrary-results { >+#overdrive-results, #recordedbooks-results, #openlibrary-results { > font-weight: bold; > padding-left: 1em; > } >diff --git a/opac/opac-recordedbooks-search.pl b/opac/opac-recordedbooks-search.pl >new file mode 100755 >index 0000000000..ba1ef7f7a4 >--- /dev/null >+++ b/opac/opac-recordedbooks-search.pl >@@ -0,0 +1,42 @@ >+#!/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 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, see <http://www.gnu.org/licenses>. >+ >+use strict; >+use warnings; >+ >+use CGI qw ( -utf8 ); >+ >+use C4::Auth qw(:DEFAULT); >+use C4::Output; >+ >+my $cgi = new CGI; >+ >+# Getting the template and auth >+my ($template, $loggedinuser, $cookie) >+= get_template_and_user({template_name => "opac-recordedbooks-search.tt", >+ query => $cgi, >+ type => "opac", >+ debug => 1, >+ authnotrequired => 1, >+ }); >+ >+$template->{'VARS'}->{'q'} = $cgi->param('q'); >+$template->{'VARS'}->{'limit'} = C4::Context->preference('OPACnumSearchResults'); >+ >+output_html_with_http_headers $cgi, $cookie, $template->output; >diff --git a/opac/opac-search.pl b/opac/opac-search.pl >index 1d7615bc5c..76e640cd1b 100755 >--- a/opac/opac-search.pl >+++ b/opac/opac-search.pl >@@ -985,9 +985,12 @@ $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')); >+if ($offset == 0) { >+ if (IsOverDriveEnabled()) { >+ $template->param(OverDriveEnabled => 1); >+ $template->param(OverDriveLibraryID => C4::Context->preference('OverDriveLibraryID')); >+ } >+ $template->param(RecordedBooksEnabled => C4::Context->preference( 'RecordedBooksClientSecret' ) && C4::Context->preference( 'RecordedBooksLibraryID' )); > } > > $template->param( borrowernumber => $borrowernumber); >diff --git a/opac/opac-user.pl b/opac/opac-user.pl >index 4e54afcf5b..2b5a7e0c52 100755 >--- a/opac/opac-user.pl >+++ b/opac/opac-user.pl >@@ -326,6 +326,7 @@ $template->param( > OverDriveCirculation => C4::Context->preference('OverDriveCirculation') || 0, > overdrive_error => scalar $query->param('overdrive_error') || undef, > overdrive_tab => scalar $query->param('overdrive_tab') || 0, >+ RecordedBooksCirculation => C4::Context->preference('RecordedBooksClientSecret') && C4::Context->preference('RecordedBooksLibraryID'), > ); > > my $patron_messages = Koha::Patron::Messages->search( >diff --git a/opac/svc/recordedbooks b/opac/svc/recordedbooks >new file mode 100755 >index 0000000000..d55a15c759 >--- /dev/null >+++ b/opac/svc/recordedbooks >@@ -0,0 +1,148 @@ >+#!/usr/bin/perl >+ >+# Copyright 2016 Catalyst IT >+# 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, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw ( -utf8 ); >+use JSON qw(encode_json); >+use C4::Auth qw(checkauth); >+use C4::Output; >+use Koha::Logger; >+use Koha::ExternalContent::RecordedBooks; >+ >+our $cgi = new CGI; >+my $logger = Koha::Logger->get({ interface => 'opac' }); >+my $page_url = $cgi->referer(); >+ >+my ( $user, $cookie, $sessionID, $flags ) = checkauth( $cgi, 1, {}, 'opac' ); >+ >+my $action = $cgi->param('action') or response_bad_request("No 'action' specified"); >+ >+($user && $sessionID) || $action eq 'search' or response_bad_request("User not logged in"); >+ >+local $@; >+my $rb = eval { Koha::ExternalContent::RecordedBooks->new({ koha_session_id => $sessionID }) }; >+unless ($rb) { >+ $logger->error($@) if $@; >+ response({ >+ error => $@, >+ is_identified => JSON::false, >+ }); >+} >+ >+my $is_identified = $rb->is_identified; >+my %data = ( >+ is_identified => $is_identified ? JSON::true : JSON::false, >+); >+response(\%data) unless $is_identified || $action eq 'search'; >+ >+eval { >+ { >+ $action eq 'search' && do { >+ my $query = $cgi->param('q'); >+ my $page = $cgi->param('page'); >+ my $page_size = $cgi->param('page_size'); >+ my $sort = $cgi->param('sort'); >+ my $res = $rb->search({ >+ query => $query, >+ page => $page, >+ page_size => $page_size, >+ sort => $sort, >+ }); >+ $data{results} = $res; >+ last; >+ }; >+ >+ $action eq 'account' && do { >+ eval { >+ $data{account} = $rb->patron; >+ $data{checkouts} = $rb->checkouts; >+ $data{holds} = $rb->holds; >+ }; >+ response_bad_request($rb->error_message($@)) if $@; >+ last; >+ }; >+ >+ $action eq 'checkout' && do { >+ my $isbn = $cgi->param('isbn') >+ or response_bad_request("No 'isbn' specified"); >+ my $format = $cgi->param('format'); >+ $data{action} = eval { $rb->checkout($isbn, $format) }; >+ response_bad_request($rb->error_message($@)) if $@; >+ >+ eval { >+ $data{checkouts} = $rb->checkouts; >+ $data{holds} = $rb->holds; >+ }; >+ $data{error} = $rb->error_message($@) if $@; >+ last; >+ }; >+ >+ $action eq 'return' && do { >+ my $isbn = $cgi->param('isbn') >+ or response_bad_request("No 'isbn' specified"); >+ $data{action} = eval { $rb->return($isbn) }; >+ response_bad_request($rb->error_message($@)) if $@; >+ >+ $data{checkouts} = eval { $rb->checkouts }; >+ $data{error} = $rb->error_message($@) if $@; >+ last; >+ }; >+ >+ $action eq 'place_hold' && do { >+ my $isbn = $cgi->param('isbn') >+ or response_bad_request("No 'isbn' specified"); >+ $data{action} = eval { $rb->place_hold($isbn) }; >+ response_bad_request($rb->error_message($@)) if $@; >+ >+ $data{holds} = eval { $rb->holds }; >+ $data{error} = $rb->error_message($@) if $@; >+ last; >+ }; >+ >+ $action eq 'remove_hold' && do { >+ my $isbn = $cgi->param('isbn') >+ or response_bad_request("No 'isbn' specified"); >+ $data{action} = eval { $rb->remove_hold($isbn) }; >+ response_bad_request($rb->error_message($@)) if $@; >+ >+ $data{holds} = eval { $rb->holds }; >+ $data{error} = $rb->error_message($@) if $@; >+ last; >+ }; >+ >+ response_bad_request("Invalid 'action': $action"); >+ } >+}; >+if ($@) { >+ $logger->error($@); >+ $data{error} = $rb->error_message("$@"); >+} >+ >+response(\%data); >+ >+ >+sub response_bad_request { >+ my ($error) = @_; >+ response({error => $error}, "400 $error"); >+} >+sub response { >+ my ($data, $status_line) = @_; >+ $status_line ||= "200 OK"; >+ output_with_http_headers $cgi, undef, encode_json($data), 'json', $status_line; >+ exit; >+} >-- >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 17602
:
57402
|
57403
|
57404
|
60855
|
60856
|
60857
|
61866
|
61932
|
62247
|
62248
|
62249
|
62250
|
63392
|
63778
|
63779
|
63780
|
63857
|
64070
|
64071
|
64095
|
64096
|
64098
|
64099
|
64100
|
65988
|
65989
|
66341
|
66342
|
66343
|
67236
|
67237
|
67238
|
67240
|
67859
|
67860
|
69019
|
69020
|
69021
|
69022
|
69023
|
69024
|
69025
|
69026
|
69027
|
69101
|
69357
|
69358
|
69359
|
73708
|
73709
|
73710
|
73711
|
73712
|
73713
|
73714
|
73715
|
73716
|
73717
|
73718
|
73719
|
73725
|
76180
|
76181
|
76182
|
76183
|
76184
|
76185
|
76186
|
76187
|
76188
|
76189
|
76190
|
76191
|
76192
|
76193
|
78602
|
78603
|
78604
|
78605
|
78606
|
78607
|
78608
|
78609
|
78610
|
78611
|
78612
|
78613
|
78614
|
78615
|
79247
|
79668
|
79669
|
79670
|
79671
|
79672
|
79673
|
79674
|
79675
|
79676
|
79677
|
79678
|
79679
|
79680
|
79681
|
79682
|
79752