From 7ca4d31e82a0c3d9ab12bd23eb844ecd57edcee3 Mon Sep 17 00:00:00 2001 From: Joe Atzberger Date: Wed, 21 May 2008 01:36:05 -0500 Subject: [PATCH] Tags AJAX and JSON for OPAC side. Note, all Tags js will live under KOHA.Tags namespace. See opac-tags.pl perldoc for AJAX/JSON examples. The capability is already there to be very web-servicey, even moreso than the current OPAC implementation will utilize. Signed-off-by: Joshua Ferraro --- .../prog/en/includes/doc-head-close.inc | 4 +- koha-tmpl/opac-tmpl/prog/en/js/tags.js | 76 +++++++++++++++ .../prog/en/modules/opac-results.tmpl | 5 +- .../opac-tmpl/prog/en/modules/opac-tags.tmpl | 2 +- opac/opac-tags.pl | 92 +++++++++++++++++-- 5 files changed, 166 insertions(+), 13 deletions(-) create mode 100644 koha-tmpl/opac-tmpl/prog/en/js/tags.js mode change 100755 => 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tmpl diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc b/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc index a7fc971bef..17186d21cd 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc @@ -16,7 +16,9 @@ - + + diff --git a/koha-tmpl/opac-tmpl/prog/en/js/tags.js b/koha-tmpl/opac-tmpl/prog/en/js/tags.js new file mode 100644 index 0000000000..62c66b2fdb --- /dev/null +++ b/koha-tmpl/opac-tmpl/prog/en/js/tags.js @@ -0,0 +1,76 @@ +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/opac-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/opac-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"}); + }, + + 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+ "'.");}, + failed_delete : function(arg) {return ("Error! You cannot delete the tag '" +arg+ "'. Note: you can only delete your own tags.");}, + }, +}; + diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tmpl b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tmpl old mode 100755 new mode 100644 index 7200482f74..797240d7fe --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tmpl +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tmpl @@ -53,6 +53,7 @@ $(document).ready(function(){ $("#bookbag_form").unCheckCheckboxes(); return false; }); + $(".tagbutton").click(KOHA.Tags.add_tag_button); KOHA.Google.GetCoverFromIsbn(); }); //]]> @@ -257,9 +258,9 @@ $(document).ready(function(){
" method="post" action="/cgi-bin/koha/opac-tags.pl"> " id="newtag" maxlength="100" /> - + " type="submit" value="Add" />
- " class="tagstatus" style="display:none;"> + _status" class="tagstatus" style="display:none;"> Tag status here. diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-tags.tmpl b/koha-tmpl/opac-tmpl/prog/en/modules/opac-tags.tmpl index 491f233b20..447bc5e031 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-tags.tmpl +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-tags.tmpl @@ -13,7 +13,7 @@
There was a problem with this operation: Sorry, tags are not enabled on this system. - ERROR: illegal paramter + 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. diff --git a/opac/opac-tags.pl b/opac/opac-tags.pl index 9d32fe06f9..d085003859 100755 --- a/opac/opac-tags.pl +++ b/opac/opac-tags.pl @@ -31,7 +31,7 @@ use warnings; use CGI; use CGI::Cookie; # need to check cookies before having CGI parse the POST request -use C4::Auth; +use C4::Auth qw(:DEFAULT check_cookie_auth); use C4::Context; use C4::Debug; use C4::Output 3.02 qw(:html :ajax pagination_bar); @@ -45,14 +45,34 @@ my @deltags = (); my %counts = (); my @errors = (); +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_ajax_with_http_headers $input, + "window.alert('Your CGI session cookie ($sessid) is not current. " . + "Please refresh the page and try again.');\n"; + 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 = new CGI; +my $query = ($is_ajax) ? &ajax_auth_cgi({}) : CGI->new(); unless (C4::Context->preference('TagsEnabled')) { push @errors, {+ tagsdisabled=>1 }; } else { @@ -72,13 +92,19 @@ unless (C4::Context->preference('TagsEnabled')) { } my $add_op = (scalar(keys %newtags) + scalar(@deltags)) ? 1 : 0; -my ($template, $loggedinuser, $cookie) = get_template_and_user({ - template_name => "opac-tags.tmpl", - query => $query, - type => "opac", - authnotrequired => ($add_op ? 0 : 1), # auth required to add tags - debug => 1, -}); +my ($template, $loggedinuser, $cookie); +if ($is_ajax) { + $loggedinuser = C4::Context->userenv->{'number'}; # must occur AFTER auth + $debug and print STDERR "op: $loggedinuser\n"; +} else { + ($template, $loggedinuser, $cookie) = get_template_and_user({ + template_name => "opac-tags.tmpl", + query => $query, + type => "opac", + authnotrequired => ($add_op ? 0 : 1), # auth required to add tags + debug => 1, + }); +} if ($add_op) { unless ($loggedinuser) { @@ -111,6 +137,7 @@ if (scalar @newtags_keys) { if ($result) { $counts{$biblionumber}++; } else { + push @errors, {failed_add_tag=>$clean_tag}; warn "add_tag($biblionumber,$clean_tag,$loggedinuser...) returned bad result ($result)"; } } @@ -125,6 +152,23 @@ foreach (@deltags) { } } +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); + my $err_string = ''; + if (scalar @errors) { + $err_string = "\n\talerts: ["; # open response_function + foreach (@errors) { + my $key = (keys %$_)[0]; + $err_string .= "\n\t\t KOHA.Tags.tag_message.$key(\"" . $_->{$key} . '"),'; + } + $err_string .= "\n\t],\n"; # close response_function + } + output_ajax_with_http_headers($query, "$js_reply\n$err_string};"); + exit; +} + my $results = []; my $my_tags = []; @@ -172,4 +216,34 @@ if ($add_op) { (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