From 1bed30a2a8ad2d0fc1c013c3615fe1629ebee904 Mon Sep 17 00:00:00 2001 From: Matthias Meusburger Date: Wed, 14 Oct 2009 15:04:53 +0200 Subject: [PATCH] MT 1110 : Balance cart and lists : cart is now in the intranet --- basket/basket.pl | 125 +++++ basket/downloadcart.pl | 90 ++++ basket/sendbasket.pl | 181 ++++++++ koha-tmpl/intranet-tmpl/prog/en/js/tags.js | 158 +++++++ .../jquery/plugins/jquery.dropshadow-min.js | 1 + .../prog/en/modules/basket/basket.tmpl | 436 ++++++++++++++++++ .../prog/en/modules/basket/downloadcart.tmpl | 28 ++ .../prog/en/modules/basket/sendbasket.tmpl | 42 ++ .../en/modules/basket/sendbasketform.tmpl | 38 ++ .../prog/en/modules/tags/tags.tmpl | 149 ++++++ koha-tmpl/intranet-tmpl/prog/img/cart.gif | Bin 0 -> 330 bytes tags/tags.pl | 327 +++++++++++++ 12 files changed, 1575 insertions(+) create mode 100755 basket/basket.pl create mode 100755 basket/downloadcart.pl create mode 100755 basket/sendbasket.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/js/tags.js create mode 100644 koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.dropshadow-min.js create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/basket/basket.tmpl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/basket/downloadcart.tmpl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasket.tmpl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasketform.tmpl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tags/tags.tmpl create mode 100644 koha-tmpl/intranet-tmpl/prog/img/cart.gif create mode 100755 tags/tags.pl diff --git a/basket/basket.pl b/basket/basket.pl new file mode 100755 index 0000000000..464c6d57ff --- /dev/null +++ b/basket/basket.pl @@ -0,0 +1,125 @@ +#!/usr/bin/perl + +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + + +use strict; +use warnings; +use CGI; +use C4::Koha; +use C4::Biblio; +use C4::Items; +use C4::Auth; +use C4::Output; + +my $query = new CGI; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( + { + template_name => "basket/basket.tmpl", + query => $query, + type => "intranet", + flagsrequired => { borrow => 1 }, + } +); + +my $bib_list = $query->param('bib_list'); +my $print_basket = $query->param('print'); +my $verbose = $query->param('verbose'); + +if ($verbose) { $template->param( verbose => 1 ); } +if ($print_basket) { $template->param( print_basket => 1 ); } + +my @bibs = split( /\//, $bib_list ); +my @results; + +my $num = 1; +my $marcflavour = C4::Context->preference('marcflavour'); +if (C4::Context->preference('TagsEnabled')) { + $template->param(TagsEnabled => 1); + foreach (qw(TagsShowOnList TagsInputOnList)) { + C4::Context->preference($_) and $template->param($_ => 1); + } +} + + +foreach my $biblionumber ( @bibs ) { + $template->param( biblionumber => $biblionumber ); + + my $dat = &GetBiblioData($biblionumber); + my $record = &GetMarcBiblio($biblionumber); + my $marcnotesarray = GetMarcNotes( $record, $marcflavour ); + my $marcauthorsarray = GetMarcAuthors( $record, $marcflavour ); + my $marcsubjctsarray = GetMarcSubjects( $record, $marcflavour ); + my $marcseriesarray = GetMarcSeries ($record,$marcflavour); + my $marcurlsarray = GetMarcUrls ($record,$marcflavour); + my @items = &GetItemsInfo( $biblionumber, 'opac' ); + + my $hasauthors = 0; + if($dat->{'author'} || @$marcauthorsarray) { + $hasauthors = 1; + } + + my $shelflocations =GetKohaAuthorisedValues('items.location',$dat->{'frameworkcode'}, 'opac'); + my $collections = GetKohaAuthorisedValues('items.ccode',$dat->{'frameworkcode'}, 'opac'); + + for my $itm (@items) { + if ($itm->{'location'}){ + $itm->{'location_description'} = $shelflocations->{$itm->{'location'} }; + } + } + # COinS format FIXME: for books Only + my $coins_format; + my $fmt = substr $record->leader(), 6,2; + my $fmts; + $fmts->{'am'} = 'book'; + $dat->{ocoins_format} = $fmts->{$fmt}; + + if ( $num % 2 == 1 ) { + $dat->{'even'} = 1; + } + + $num++; + $dat->{biblionumber} = $biblionumber; + $dat->{ITEM_RESULTS} = \@items; + $dat->{MARCNOTES} = $marcnotesarray; + $dat->{MARCSUBJCTS} = $marcsubjctsarray; + $dat->{MARCAUTHORS} = $marcauthorsarray; + $dat->{MARCSERIES} = $marcseriesarray; + $dat->{MARCURLS} = $marcurlsarray; + $dat->{HASAUTHORS} = $hasauthors; + + if ( C4::Context->preference("BiblioDefaultView") eq "normal" ) { + $dat->{dest} = "opac-detail.pl"; + } + elsif ( C4::Context->preference("BiblioDefaultView") eq "marc" ) { + $dat->{dest} = "opac-MARCdetail.pl"; + } + else { + $dat->{dest} = "opac-ISBDdetail.pl"; + } + push( @results, $dat ); +} + +my $resultsarray = \@results; + +# my $itemsarray=\@items; + +$template->param( + BIBLIO_RESULTS => $resultsarray, +); + +output_html_with_http_headers $query, $cookie, $template->output; diff --git a/basket/downloadcart.pl b/basket/downloadcart.pl new file mode 100755 index 0000000000..9733c116da --- /dev/null +++ b/basket/downloadcart.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +# Copyright 2009 BibLibre +# +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use strict; +use warnings; + +use CGI; +use Encode qw(encode); +use Switch; + +use C4::Auth; +use C4::Biblio; +use C4::Items; +use C4::Output; +use C4::VirtualShelves; +use C4::Record; +use C4::Ris; +use C4::Csv; +use utf8; +use open qw( :std :utf8); +my $query = new CGI; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( + { + template_name => "basket/downloadcart.tmpl", + query => $query, + type => "intranet", + authnotrequired => 0, + flagsrequired => { borrow => 1 }, + } +); + +my $bib_list = $query->param('bib_list'); +my $format = $query->param('format'); +my $dbh = C4::Context->dbh; + +if ($bib_list && $format) { + + my @bibs = split( /\//, $bib_list ); + + my $marcflavour = C4::Context->preference('marcflavour'); + my $output; + + # retrieve biblios from shelf + my $firstpass = 1; + foreach my $biblio (@bibs) { + + my $record = GetMarcBiblio($biblio); + + switch ($format) { + case "iso2709" { $output .= $record->as_usmarc(); } + case "ris" { $output .= marc2ris($record); } + case "bibtex" { $output .= marc2bibtex($record, $biblio); } + # We're in the case of a csv profile (firstpass is used for headers printing) : + case /^\d+$/ { $output .= marc2csv($record, $format, $firstpass); } + } + $firstpass = 0; + + } + + # If it was a CSV export we change the format after the export so the file extension is fine + $format = "csv" if ($format =~ m/^\d+$/); + + print $query->header( + -type => 'application/octet-stream', + -'Content-Transfer-Encoding' => 'binary', + -attachment=>"cart.$format"); + print $output; + +} else { + $template->param(csv_profiles => GetCsvProfilesLoop()); + $template->param(bib_list => $bib_list); + output_html_with_http_headers $query, $cookie, $template->output; +} diff --git a/basket/sendbasket.pl b/basket/sendbasket.pl new file mode 100755 index 0000000000..6efa6bcce1 --- /dev/null +++ b/basket/sendbasket.pl @@ -0,0 +1,181 @@ +#!/usr/bin/perl + +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use strict; +use warnings; + +use CGI; +use Encode qw(encode); + +use Mail::Sendmail; +use MIME::QuotedPrint; +use MIME::Base64; +use C4::Biblio; +use C4::Items; +use C4::Auth; +use C4::Output; +use C4::Biblio; + +my $query = new CGI; + +my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( + { + template_name => "basket/sendbasketform.tmpl", + query => $query, + type => "intranet", + authnotrequired => 0, + flagsrequired => { borrow => 1 }, + } +); + +my $bib_list = $query->param('bib_list'); +my $email_add = $query->param('email_add'); +my $email_sender = $query->param('email_sender'); + +my $dbh = C4::Context->dbh; + +if ( $email_add ) { + my $email_from = C4::Context->preference('KohaAdminEmailAddress'); + my $comment = $query->param('comment'); + my %mail = ( + To => $email_add, + From => $email_from + ); + + my ( $template2, $borrowernumber, $cookie ) = get_template_and_user( + { + template_name => "basket/sendbasket.tmpl", + query => $query, + type => "intranet", + authnotrequired => 0, + flagsrequired => { borrow => 1 }, + } + ); + + my @bibs = split( /\//, $bib_list ); + my @results; + my $iso2709; + my $marcflavour = C4::Context->preference('marcflavour'); + foreach my $biblionumber (@bibs) { + $template2->param( biblionumber => $biblionumber ); + + my $dat = GetBiblioData($biblionumber); + my $record = GetMarcBiblio($biblionumber); + my $marcnotesarray = GetMarcNotes( $record, $marcflavour ); + my $marcauthorsarray = GetMarcAuthors( $record, $marcflavour ); + my $marcsubjctsarray = GetMarcSubjects( $record, $marcflavour ); + + my @items = &GetItemsInfo( $biblionumber, 'opac' ); + + my $hasauthors = 0; + if($dat->{'author'} || @$marcauthorsarray) { + $hasauthors = 1; + } + + + $dat->{MARCNOTES} = $marcnotesarray; + $dat->{MARCSUBJCTS} = $marcsubjctsarray; + $dat->{MARCAUTHORS} = $marcauthorsarray; + $dat->{HASAUTHORS} = $hasauthors; + $dat->{'biblionumber'} = $biblionumber; + $dat->{ITEM_RESULTS} = \@items; + + $iso2709 .= $record->as_usmarc(); + + push( @results, $dat ); + } + + my $resultsarray = \@results; + $template2->param( + BIBLIO_RESULTS => $resultsarray, + email_sender => $email_sender, + comment => $comment + ); + + # Getting template result + my $template_res = $template2->output(); + my $body; + + # Analysing information and getting mail properties + if ( $template_res =~ /\n(.*)\n/s ) { + $mail{'subject'} = $1; + } + else { $mail{'subject'} = "no subject"; } + + my $email_header = ""; + if ( $template_res =~ /
\n(.*)\n/s ) { + $email_header = $1; + } + + my $email_file = "basket.txt"; + if ( $template_res =~ /\n(.*)\n/s ) { + $email_file = $1; + } + + if ( $template_res =~ /\n(.*)\n/s ) { $body = encode_qp($1); } + + my $boundary = "====" . time() . "===="; + + # $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\""; + # + # $email_header = encode_qp($email_header); + # + # $boundary = "--".$boundary; + # + # # Writing mail + # $mail{body} = + $mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\""; + my $isofile = encode_base64(encode("UTF-8", $iso2709)); + $boundary = '--' . $boundary; + $mail{body} = <param( SENT => "1" ); + } + else { + # do something if it doesnt work.... + warn "Error sending mail: $Mail::Sendmail::error \n"; + $template->param( error => 1 ); + } + $template->param( email_add => $email_add ); + output_html_with_http_headers $query, $cookie, $template->output; +} +else { + $template->param( bib_list => $bib_list ); + $template->param( + url => "/cgi-bin/koha/basket/sendbasket.pl", + suggestion => C4::Context->preference("suggestion"), + virtualshelves => C4::Context->preference("virtualshelves"), + ); + output_html_with_http_headers $query, $cookie, $template->output; +} diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/tags.js b/koha-tmpl/intranet-tmpl/prog/en/js/tags.js new file mode 100644 index 0000000000..9c117d0b33 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/js/tags.js @@ -0,0 +1,158 @@ +if (typeof KOHA == "undefined" || !KOHA) { + var KOHA = {}; +} + +/** +* A namespace for Tags related functions. +* readCookie is expected to already be declared. That's why the assignment below is unscoped. +* readCookie should be from basket.js or undefined. + +$.ajaxSetup({ + url: "/cgi-bin/koha/tags/tags.pl", + type: "POST", + dataType: "script" +}); +*/ +if (typeof(readCookie) == "undefined") { + readCookie = function (name) { // from http://www.quirksmode.org/js/cookies.html + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' '){ c = c.substring(1,c.length); } + if (c.indexOf(nameEQ) == 0){ return c.substring(nameEQ.length,c.length); } + } + return null; + } +} +KOHA.Tags = { + add_tag_button: function(){ + var mybibnum = $(this).attr("title"); + var mynewtag = "newtag" + mybibnum; + var mytagid = "#" + mynewtag; + var mydata = {CGISESSID: readCookie('CGISESSID')}; // Someday this should be OPACSESSID + mydata[mynewtag] = $(mytagid).val(); // need [bracket] for variable property id + var response; // AJAX from server will assign value to response. + $.post( + "/cgi-bin/koha/tags/tags.pl", + mydata, + function(data){ + // alert("AJAX Response: " + data); + eval(data); + // alert("counts: " + response["added"] + response["deleted"] + response["errors"]); + KOHA.Tags.set_tag_status( + mytagid + "_status", + KOHA.Tags.common_status(response["added"], response["deleted"], response["errors"]) + ); + if (response.alerts) { + alert(response.alerts.join("\n\n")); + } + }, + 'script' + ); + return false; + }, + common_status : function(addcount, delcount, errcount) { + var cstat = ""; + if (addcount && addcount > 0) {cstat += _("Added ") + addcount + (addcount==1 ? _(" tag") : _(" tags")) + ". " ;} + if (delcount && delcount > 0) {cstat += _("Deleted ") + delcount + (delcount==1 ? _(" tag") : _(" tags")) + ". " ;} + if (errcount && errcount > 0) {cstat += (errcount==1 ? _("ERROR") : errcount + _(" ERRORS")) + _(" during operation.");} + return cstat; + }, + set_tag_status : function(tagid, newstatus) { + $(tagid).html(newstatus); + $(tagid).css({display:"inline"}); + }, + append_tag_status : function(tagid, newstatus) { + $(tagid).append(newstatus); + $(tagid).css({display:"inline"}); + }, + + tag_message: { + tagsdisabled : function(arg) {return (_("Sorry, tags are not enabled on this system."));}, + scrubbed_all_bad : function(arg) {return (_("Error! Your tag was entirely markup code. It was NOT added. Please try again with plain text."));}, + badparam : function(arg) {return (_("Error! Illegal parameter '" +arg+ "'."));}, + scrubbed : function(arg) {return (_("Note: your tag contained markup code that was removed. The tag was added as '" +arg+ "'."));}, + failed_add_tag : function(arg) {return (_("Error! The add_tag operation failed on '" +arg+ "'. Note: you can only tag an item with a given term once. Check 'My Tags' to see your current tags."));}, + failed_delete : function(arg) {return (_("Error! You cannot delete the tag '" +arg+ "'. Note: you can only delete your own tags."));}, + login : function(arg) {return (_("You must be logged in to add tags."));} + }, + + // Used to tag multiple items at once. The main difference + // is that status is displayed on a per item basis. + add_multitags_button : function(bibarray, tag){ + var mydata = {CGISESSID: readCookie('CGISESSID')}; // Someday this should be OPACSESSID + for (var i = 0; i < bibarray.length; i++) { + var mynewtag = "newtag" + bibarray[i]; + mydata[mynewtag] = tag; + } + var response; // AJAX from server will assign value to response. + $.post( + "/cgi-bin/koha/tags/tags.pl", + mydata, + function(data){ + eval(data); + $(".tagstatus").empty(); + var bibErrors = false; + + // Display the status for each tagged bib + for (var i = 0; i < bibarray.length; i++) { + var bib = bibarray[i]; + var mytagid = "#newtag" + bib; + var status = ""; + + // Number of tags added. + if (response[bib]) { + var added = response[bib]["added"]; + if (added > 0) { + status = "Added " + added + (added == 1 ? " tag" : " tags") + ". "; + KOHA.Tags.set_tag_status(mytagid + "_status", status); + } + + // Show a link that opens an error dialog, if necessary. + var errors = response[bib]["errors"]; + if (errors.length > 0) { + bibErrors = true; + var errid = "tagerr_" + bib; + var errstat = ""; + errstat += "Error" + (errors.length > 1 ? "s" : "") + " adding tag."; + errstat += ""; + KOHA.Tags.append_tag_status(mytagid + "_status", errstat); + var errmsg = ""; + for (var e = 0; e < errors.length; e++){ + if (e) { + errmsg += "\n\n"; + } + errmsg += errors[e]; + } + $("#" + errid).click(function(){ + alert(errmsg); + }); + } + } + } + + if (bibErrors || response["global_errors"]) { + var msg = ""; + if (bibErrors) { + msg = "Unable to add one or more tags."; + } + + // Show global errors in a dialog. + if (response["global_errors"]) { + var global_errors = response["global_errors"]; + var msg; + for (var e = 0; e < global_errors.length; e++) { + msg += "\n\n"; + msg += response.alerts[global_errors[e]]; + } + } + alert(msg); + } + }, + 'script' + ); + return false; + } +}; + diff --git a/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.dropshadow-min.js b/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.dropshadow-min.js new file mode 100644 index 0000000000..9b1b1fba65 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.dropshadow-min.js @@ -0,0 +1 @@ +(function(B){var A=1;B.fn.dropShadow=function(C){var D=B.extend({left:4,top:4,blur:2,opacity:0.5,color:"black",swap:false},C);var E=B([]);this.not(".dropShadow").each(function(){var N=B(this);var J=[];var G=(D.blur<=0)?0:D.blur;var M=(G==0)?D.opacity:D.opacity/(G*8);var O=(D.swap)?A:A+1;var F=(D.swap)?A+1:A;var P;if(this.id){P=this.id+"_dropShadow"}else{P="ds"+(1+Math.floor(9999*Math.random()))}B.data(this,"shadowId",P);B.data(this,"shadowOptions",C);N.attr("shadowId",P).css("zIndex",O);if(N.css("position")!="absolute"){N.css({position:"relative",zoom:1})}bgColor=N.css("backgroundColor");if(bgColor=="rgba(0, 0, 0, 0)"){bgColor="transparent"}if(bgColor!="transparent"||N.css("backgroundImage")!="none"||this.nodeName=="SELECT"||this.nodeName=="INPUT"||this.nodeName=="TEXTAREA"){J[0]=B("
").css("background",D.color)}else{J[0]=N.clone().removeAttr("id").removeAttr("name").removeAttr("shadowId").css("color",D.color)}J[0].addClass("dropShadow").css({height:N.outerHeight(),left:G,opacity:M,position:"absolute",top:G,width:N.outerWidth(),zIndex:F});var L=(8*G)+1;for(K=1;K0){J[K].css({left:I*2,top:0});J[K+1].css({left:I*4,top:I*2});J[K+2].css({left:I*2,top:I*4});J[K+3].css({left:0,top:I*2});J[K+4].css({left:I*3,top:I});J[K+5].css({left:I*3,top:I*3});J[K+6].css({left:I,top:I*3});J[K+7].css({left:I,top:I});K+=8;I--}var H=B("
").attr("id",P).addClass("dropShadow").css({left:N.position().left+D.left-G,marginTop:N.css("marginTop"),marginRight:N.css("marginRight"),marginBottom:N.css("marginBottom"),marginLeft:N.css("marginLeft"),position:"absolute",top:N.position().top+D.top-G,zIndex:F});for(K=0;K +Koha Online Catalog › Your Cart + + + +/includes/favicon.ico" type="image/x-icon" /> + + + + + + + + + + +
+
+ +

Your Cart

+ +
+ +
+ + + +

Select All Clear All | Selected items : + +Remove + + + | Add to a list + + + + | Place Hold + + + + + + +

+
+ +

+ + + + + + " name="bib" id="bib" onclick="selRecord(value,checked)" /> + + + + +

+ + &rft.btitle=&rft.date=&rft.tpages=&rft.isbn=&rft.aucorp=&rft.place=&rft.pub=&rft.edition=&rft.series=&rft.genre="> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ISBN
Author(s) + +

+ + + +

+ + + +

+ + +
Publisher +
Details
Collection
Subject(s) +

+ +

+
Copyright
Notes + +

-

+
Unified title
Serial
Dewey
Classification
LCCN
URL(s) + +

+
+ + +
+

Location(s) +

+ + + () + +

+ This record has no items.
+ +
+ + + +

+

+ Select All + Clear All + | Selected items : + +Remove + + + | Add to a list + + + + | Place Hold + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + +
 TitleItem TypeLocation
+ " name="bib" id="bib" onclick="selRecord(value,checked);" /> + + ',)"> + + + +

- + + - + +

+ +

+ + + &rft.btitle=&rft.date=&rft.tpages=&rft.isbn=&rft.aucorp=&rft.place=&rft.pub=&rft.edition=&rft.series=&rft.genre="> +
_status" class="tagstatus results_summary" style="display:none">Tag status here.
+ +
+

+ + + () + +

+ This record has no items.
+ + + +<< Back to Cart + +
+ +
+ + +
+
+ + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/downloadcart.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/downloadcart.tmpl new file mode 100644 index 0000000000..d05e2a208b --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/downloadcart.tmpl @@ -0,0 +1,28 @@ +Download shelf + + + + Your Download should automatically start + +
+ + + " /> + +
+ +

Close this window

+
+ + + + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasket.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasket.tmpl new file mode 100644 index 0000000000..033c4d21d1 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasket.tmpl @@ -0,0 +1,42 @@ + +Your Cart + + +
+Hi, + +Here is your cart, sent from our online catalog. + +Please note that the attached file is a MARC biblographic records file +which can be imported into a Personal Bibliographic Software like EndNote, +Reference Manager or ProCite. + + + +--------------------------------------------- + + + + +Author(s): ; ; +ISBN: +Published by: in , , +Collection: +Subject: +Copyright year: +Notes : +Unified title: +Serial: +Dewey: +Classification: +LCCN: +URL : +In the online catalog: +/cgi-bin/koha/opac-detail.pl?biblionumber= +Items : + () + +--------------------------------------------- + + + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasketform.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasketform.tmpl new file mode 100644 index 0000000000..9caef3c3de --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/basket/sendbasketform.tmpl @@ -0,0 +1,38 @@ +Koha Online Catalog › Sending Your Cart + + + +
+ + +

Message Sent

+

The cart was sent to:

+

Close window

+ + +

Problem sending the cart...

+ + + + +
" method="post"> + +
+Sending your cart +
  1. + + +
  2. +
  3. + + +
  4. +
  5. + " /> +
+
Cancel
+
+ +
+ + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tags/tags.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/tags/tags.tmpl new file mode 100644 index 0000000000..8681a8aa12 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tags/tags.tmpl @@ -0,0 +1,149 @@ +Koha Online Catalog › Tags + + + + + + +
+
+ + +
+
+
+ + +
There was a problem with this operation: + Sorry, tags are not enabled on this system. + ERROR: illegal parameter + ERROR: You must log in to complete that action. + ERROR: You cannot delete the tag . +
Note: you can only delete your own tags. + Note: your tag contained markup code that was removed. +
The tag was added as "". + Note: your tag was entirely markup code. It was NOT added. +
Please try again with plain text. + Unrecognized error. + +
+ + +

All Tags

+ +
+
Show up to " /> + tags from other users. + + + + + + Log in to see your own saved tags. + + ">Show my tags + &hidemytags=1">Hide my tags + +
+
+ + +
+ + " title=""> + &q="> + + + + +
+ + + +
tagtags successfully added.
+ + +
tagtags successfully deleted.
+ + + + + +
+

My Tags

+ + + + + + + + + + +
TermTitleDate AddedDelete
&q="> + + "> + " value="Delete" />
+
+ + + +
+
+
+
+ +
+ + +
+ +
+ + diff --git a/koha-tmpl/intranet-tmpl/prog/img/cart.gif b/koha-tmpl/intranet-tmpl/prog/img/cart.gif new file mode 100644 index 0000000000000000000000000000000000000000..560cc288f976dacc5e2ee8e7c8ce3f56d9e8fb9e GIT binary patch literal 330 zcmZ?wbhEHb8Jb~xA-+}wa!~;SGdHhZlhD#imQuTiylanF?Z%|3#~CO9 zia%Kx85nec5C}kiVqi;m;A(Z%k?QO}{_2Fvyjea>i!M3{Sa5JSdf#DTYR!KottTMP z&+`dp=$HJGPP^-+}wa2Hpb X?V`fYw}_36oz0z#Yo(HlBZD;n`Q~Q; literal 0 HcmV?d00001 diff --git a/tags/tags.pl b/tags/tags.pl new file mode 100755 index 0000000000..bfce9ccd56 --- /dev/null +++ b/tags/tags.pl @@ -0,0 +1,327 @@ +#!/usr/bin/perl + +# Copyright 2000-2002 Katipo Communications +# +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + + +=head1 + +TODO :: Description here + +C4::Scrubber is used to remove all markup content from the sumitted text. + +=cut + +use strict; +use warnings; +use CGI; +use CGI::Cookie; # need to check cookies before having CGI parse the POST request + +use C4::Auth qw(:DEFAULT check_cookie_auth); +use C4::Context; +use C4::Debug; +use C4::Output 3.02 qw(:html :ajax pagination_bar); +use C4::Dates qw(format_date); +use C4::Scrubber; +use C4::Biblio; +use C4::Tags qw(add_tag get_approval_rows get_tag_rows remove_tag); + +my %newtags = (); +my @deltags = (); +my %counts = (); +my @errors = (); +my $perBibResults = {}; + +# Indexes of @errors that do not apply to a particular biblionumber. +my @globalErrorIndexes = (); + +sub ajax_auth_cgi ($) { # returns CGI object + my $needed_flags = shift; + my %cookies = fetch CGI::Cookie; + my $input = CGI->new; + my $sessid = $cookies{'CGISESSID'}->value || $input->param('CGISESSID'); + my ($auth_status, $auth_sessid) = check_cookie_auth($sessid, $needed_flags); + $debug and + print STDERR "($auth_status, $auth_sessid) = check_cookie_auth($sessid," . Dumper($needed_flags) . ")\n"; + if ($auth_status ne "ok") { + output_with_http_headers $input, undef, + "window.alert('Your CGI session cookie ($sessid) is not current. " . + "Please refresh the page and try again.');\n", 'js'; + exit 0; + } + $debug and print STDERR "AJAX request: " . Dumper($input), + "\n(\$auth_status,\$auth_sessid) = ($auth_status,$auth_sessid)\n"; + return $input; +} + +# The trick here is to support multiple tags added to multiple bilbios in one POST. +# The HTML might not use this, but it makes it more web-servicey from the start. +# So the name of param has to have biblionumber built in. +# For lack of anything more compelling, we just use "newtag[biblionumber]" +# We split the value into tags at comma and semicolon + +my $is_ajax = is_ajax(); +my $openadds = C4::Context->preference('TagsModeration') ? 0 : 1; +my $query = ($is_ajax) ? &ajax_auth_cgi({}) : CGI->new(); +unless (C4::Context->preference('TagsEnabled')) { + push @errors, {+ tagsdisabled=>1 }; + push @globalErrorIndexes, $#errors; +} else { + foreach ($query->param) { + if (/^newtag(.*)/) { + my $biblionumber = $1; + unless ($biblionumber =~ /^\d+$/) { + $debug and warn "$_ references non numerical biblionumber '$biblionumber'"; + push @errors, {+'badparam' => $_ }; + push @globalErrorIndexes, $#errors; + next; + } + $newtags{$biblionumber} = $query->param($_); + } elsif (/^del(\d+)$/) { + push @deltags, $1; + } + } +} + +my $add_op = (scalar(keys %newtags) + scalar(@deltags)) ? 1 : 0; +my ($template, $loggedinuser, $cookie); +if ($is_ajax) { + $loggedinuser = C4::Context->userenv->{'id'}; # must occur AFTER auth + $debug and print STDERR "op: $loggedinuser\n"; +} else { + ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "tags/tags.tmpl", + query => $query, + type => "intranet", + authnotrequired => ($add_op ? 0 : 1), # auth required to add tags + debug => 1, + }); +} + +if ($add_op) { + unless ($loggedinuser) { + push @errors, {+'login' => 1 }; + push @globalErrorIndexes, $#errors; + %newtags=(); # zero out any attempted additions + @deltags=(); # zero out any attempted deletions + } +} + +my $scrubber; +my @newtags_keys = (keys %newtags); +if (scalar @newtags_keys) { + $scrubber = C4::Scrubber->new(); + foreach my $biblionumber (@newtags_keys) { + my $bibResults = {adds=>0, errors=>[]}; + my @values = split /[;,]/, $newtags{$biblionumber}; + foreach (@values) { + s/^\s*(.+)\s*$/$1/; + my $clean_tag = $scrubber->scrub($_); + unless ($clean_tag eq $_) { + if ($clean_tag =~ /\S/) { + push @errors, {scrubbed=>$clean_tag}; + push @{$bibResults->{errors}}, {scrubbed=>$clean_tag}; + } else { + push @errors, {scrubbed_all_bad=>1}; + push @{$bibResults->{errors}}, {scrubbed_all_bad=>1}; + next; # we don't add it if there's nothing left! + } + } + my $result = ($openadds) ? + add_tag($biblionumber,$clean_tag,$loggedinuser,$loggedinuser) : # pre-approved + add_tag($biblionumber,$clean_tag,$loggedinuser) ; + if ($result) { + $counts{$biblionumber}++; + $bibResults->{adds}++; + } else { + push @errors, {failed_add_tag=>$clean_tag}; + push @{$bibResults->{errors}}, {failed_add_tag=>$clean_tag}; + $debug and warn "add_tag($biblionumber,$clean_tag,$loggedinuser...) returned bad result (" . (defined $result ? $result : 'UNDEF') .")"; + } + } + $perBibResults->{$biblionumber} = $bibResults; + } +} +my $dels = 0; +foreach (@deltags) { + if (remove_tag($_,$loggedinuser)) { + $dels++; + } else { + push @errors, {failed_delete=>$_}; + } +} + +if ($is_ajax) { + my $sum = 0; + foreach (values %counts) {$sum += $_;} + my $js_reply = sprintf("response = {\n\tadded: %d,\n\tdeleted: %d,\n\terrors: %d",$sum,$dels,scalar @errors); + + # If no add attempts were made, flag global errors. + if (@globalErrorIndexes) { + $js_reply .= ",\n\tglobal_errors: ["; + my $first = 1; + foreach (@globalErrorIndexes) { + $js_reply .= "," unless $first; + $first = 0; + $js_reply .= "\n\t\t$_"; + } + $js_reply .= "\n\t]"; + } + + my $err_string = ''; + if (scalar @errors) { + $err_string = ",\n\talerts: ["; # open response_function + my $i = 1; + foreach (@errors) { + my $key = (keys %$_)[0]; + $err_string .= "\n\t\t KOHA.Tags.tag_message.$key(\"" . $_->{$key} . '")'; + if($i < scalar @errors){ $err_string .= ","; } + $i++; + } + $err_string .= "\n\t]\n"; # close response_function + } + + # Add per-biblionumber results for use on results page + my $js_perbib = ""; + for my $bib (keys %$perBibResults) { + my $bibResult = $perBibResults->{$bib}; + my $js_bibres = ",\n\t$bib: {\n\t\tadded: $bibResult->{adds}"; + $js_bibres .= ",\n\t\terrors: ["; + my $i = 0; + foreach (@{$bibResult->{errors}}) { + $js_bibres .= "," if ($i); + my $key = (keys %$_)[0]; + $js_bibres .= "\n\t\t\t KOHA.Tags.tag_message.$key(\"" . $_->{$key} . '")'; + $i++; + } + $js_bibres .= "\n\t\t]\n\t}"; + $js_perbib .= $js_bibres; + } + + output_with_http_headers($query, undef, "$js_reply\n$err_string\n$js_perbib\n};", 'js'); + exit; +} + +my $results = []; +my $my_tags = []; + +if ($loggedinuser) { + $my_tags = get_tag_rows({borrowernumber=>$loggedinuser}); + foreach (@$my_tags) { + my $biblio = GetBiblioData($_->{biblionumber}); + $_->{bib_summary} = $biblio->{title}; + ($biblio->{author}) and $_->{bib_summary} .= " by " . $biblio->{author}; + my $date = $_->{date_created} || ''; + $date =~ /\s+(\d{2}\:\d{2}\:\d{2})/; + $_->{time_created_display} = $1; + $_->{date_created_display} = format_date($_->{date_created}); + } +} + +$template->param(tagsview => 1, +dateformat => C4::Context->preference("dateformat")); + +if ($add_op) { + my $adds = 0; + for (values %counts) {$adds += $_;} + $template->param( + add_op => 1, + added_count => $adds, + deleted_count => $dels, + ); +} else { + my ($arg,$limit,$mine); + my $hardmax = 100; # you might disagree what this value should be, but there definitely should be a max + $limit = $query->param('limit') || $hardmax; + $mine = $query->param('mine') || 0; # set if the patron want to see only his own tags. + ($limit =~ /^\d+$/ and $limit <= $hardmax) or $limit = $hardmax; + $template->param(limit => $limit); + my $arghash = {approved=>1, limit=>$limit, 'sort'=>'-weight_total'}; + $arghash->{'borrowernumber'} = $loggedinuser if $mine; + # ($openadds) or $arghash->{approved} = 1; + if ($arg = $query->param('tag')) { + $arghash->{term} = $arg; + } elsif ($arg = $query->param('biblionumber')) { + $arghash->{biblionumber} = $arg; + } + $results = get_approval_rows($arghash); + + my $count = scalar @$results; + $template->param(TAGLOOP_COUNT => $count, mine => $mine); + # Here we make a halfhearted attempt to separate the tags into "strata" based on weight_total + # FIXME: code4lib probably has a better algorithm, iirc + # FIXME: when we get a better algorithm, move to C4 + my $maxstrata = 5; + my $strata = 1; + my $previous = 0; + my $chunk = ($count/$maxstrata)/2; + my $total = 0; + my %cloud; + foreach (reverse @$results) { + my $current = $_->{weight_total}; + $total++; + $cloud{$strata}++; + if ($current == $previous) { + $_->{cloudweight} = $strata; + next; + } + if ($strata < $maxstrata and + ($cloud{$strata} > $chunk or + $count-$total <= $maxstrata-$strata)) { + $strata++; + } + $_->{cloudweight} = $strata; + $previous = $current; + } +} +(scalar @errors ) and $template->param(ERRORS => \@errors); +my @orderedresult = sort { $a->{'term'} cmp $b->{'term'} } @$results; +(scalar @$results) and $template->param(TAGLOOP => \@orderedresult ); +(scalar @$my_tags) and $template->param(MY_TAGS => $my_tags); + +output_html_with_http_headers $query, $cookie, $template->output; +__END__ + +=head1 EXAMPLE AJAX POST PARAMETERS + +CGISESSID 7c6288263107beb320f70f78fd767f56 +newtag396 fire,+foobar,+ + +So this request is trying to add 3 tags to biblio #396. The CGISESSID is the same as that the browser would +typically communicate using cookies. If it is valid, the server will split the value of "newtag396" and +process the components for addition. In this case the intended tags are: + fire + foobar + + +The first tag is acceptable. The second will be scrubbed of markup, resulting in the tag "foobar". +The third tag is all markup, and will be rejected. + +=head1 EXAMPLE AJAX JSON response + +response = { + added: 2, + deleted: 0, + errors: 2, + alerts: [ + KOHA.Tags.tag_message.scrubbed("foobar"), + KOHA.Tags.tag_message.scrubbed_all_bad("1"), + ], +}; + +=cut + -- 2.39.5