Add error feedback and Scrubber to OPAC tags page. Beginnings of ajax code.
[koha.git] / opac / opac-tags.pl
1 #!/usr/bin/perl
2
3 # Copyright 2000-2002 Katipo Communications
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA  02111-1307 USA
19
20
21 =head1 
22
23 TODO :: Description here
24
25 C4::Scrubber is used to remove all markup content from the sumitted text.
26
27 =cut
28
29 use strict;
30 use warnings;
31 use CGI;
32 use CGI::Cookie; # need to check cookies before having CGI parse the POST request
33
34 use C4::Auth;
35 use C4::Context;
36 use C4::Debug;
37 use C4::Output 3.02 qw(:html :ajax pagination_bar);
38 use C4::Dates qw(format_date);
39 use C4::Scrubber;
40 use C4::Biblio;
41 use C4::Tags qw(add_tag get_tags get_tag_rows remove_tag);
42
43 my %newtags = ();
44 my @deltags = ();
45 my %counts  = ();
46 my @errors  = ();
47
48 # The trick here is to support multiple tags added to multiple bilbios in one POST.
49 # The HTML might not use this, but it makes it more web-servicey from the start.
50 # So the name of param has to have biblionumber built in.
51 # For lack of anything more compelling, we just use "newtag[biblionumber]"
52 # We split the value into tags at comma and semicolon
53
54 my $openadds = C4::Context->preference('TagsModeration') ? 0 : 1;
55 my $query = new CGI;
56 unless (C4::Context->preference('TagsEnabled')) {
57         push @errors, {+ tagsdisabled=>1 };
58 } else {
59         foreach ($query->param) {
60                 if (/^newtag(.*)/) {
61                         my $biblionumber = $1;
62                         unless ($biblionumber =~ /^\d+$/) {
63                                 $debug and warn "$_ references non numerical biblionumber '$biblionumber'";
64                                 push @errors, {+'badparam' => $_ };
65                                 next;
66                         }
67                         $newtags{$biblionumber} = $query->param($_);
68                 } elsif (/^del(\d+)$/) {
69                         push @deltags, $1;
70                 }
71         }
72 }
73
74 my $add_op = (scalar(keys %newtags) + scalar(@deltags)) ? 1 : 0;
75 my ($template, $loggedinuser, $cookie) = get_template_and_user({
76         template_name   => "opac-tags.tmpl",
77         query           => $query,
78         type            => "opac",
79         authnotrequired => ($add_op ? 0 : 1),   # auth required to add tags
80         debug           => 1,
81 });
82
83 if ($add_op) {
84         unless ($loggedinuser) {
85                 push @errors, {+'login' => 1 };
86                 %newtags=();    # zero out any attempted additions
87                 @deltags=();    # zero out any attempted deletions
88         }
89 }
90
91 my $scrubber;
92 my @newtags_keys = (keys %newtags);
93 if (scalar @newtags_keys) {
94         $scrubber = C4::Scrubber->new();
95         foreach my $biblionumber (@newtags_keys) {
96                 my @values = split /[;,]/, $newtags{$biblionumber};
97                 foreach (@values) {
98                         s/^\s*(.+)\s*$/$1/;
99                         my $clean_tag = $scrubber->scrub($_);
100                         unless ($clean_tag eq $_) {
101                                 if ($clean_tag =~ /\S/) {
102                                         push @errors, {scrubbed=>$clean_tag};
103                                 } else {
104                                         push @errors, {scrubbed_all_bad=>1};
105                                         next;   # we don't add it if there's nothing left!
106                                 }
107                         }
108                         my $result = ($openadds) ?
109                                 add_tag($biblionumber,$clean_tag,$loggedinuser,0) : # pre-approved
110                                 add_tag($biblionumber,$clean_tag,$loggedinuser)   ;
111                         if ($result) {
112                                 $counts{$biblionumber}++;
113                         } else {
114                                 warn "add_tag($biblionumber,$clean_tag,$loggedinuser...) returned bad result ($result)";
115                         }
116                 }
117         }
118 }
119 my $dels = 0;
120 foreach (@deltags) {
121         if (remove_tag($_,$loggedinuser)) {
122                 $dels++;
123         } else {
124                 push @errors, {failed_delete=>$_};
125         }
126 }
127
128 my $results = [];
129 my $my_tags = [];
130
131 if ($loggedinuser) {
132         $my_tags = get_tag_rows({borrowernumber=>$loggedinuser});
133         foreach (@$my_tags) {
134                 my $biblio = GetBiblioData($_->{biblionumber});
135                 $_->{bib_summary} = $biblio->{title}; 
136                 ($biblio->{author}) and $_->{bib_summary} .= " by " . $biblio->{author};
137                 my $date = $_->{date_created} || '';
138                 $date =~ /\s+(\d{2}\:\d{2}\:\d{2})/;
139                 $_->{time_created_display} = $1;
140                 $_->{date_created_display} = format_date($_->{date_created});
141         }
142 }
143 $template->param(tagsview => 1,);
144 if ($add_op) {
145         my $adds = 0;
146         for (values %counts) {$adds += $_;}
147         $template->param(
148                 add_op => 1,
149                 added_count => $adds,
150                 deleted_count => $dels,
151         );
152 } else {
153         my ($arg,$limit,$tmpresults);
154         my $hardmax = 100;      # you might disagree what this value should be, but there definitely should be a max
155         $limit = $query->param('limit') || $hardmax;
156         ($limit =~ /^\d+$/ and $limit <= $hardmax) or $limit = $hardmax;
157         if ($arg = $query->param('tag')) {
158                 $tmpresults = get_tags({term => $arg, limit=>$limit, 'sort'=>'-weight'});
159         } elsif ($arg = $query->param('biblionumber')) {
160                 $tmpresults = get_tags({biblionumber => $arg, limit=>$limit, 'sort'=>'-weight'});
161         } else {
162                 $tmpresults = get_tags({limit=>$limit, 'sort'=>'-weight'});
163         }
164         my %uniq;
165         foreach (@$tmpresults) {
166                 $uniq{$_->{term}}++ and next;
167                 push @$results, $_;
168         }
169 }
170 (scalar @errors  ) and $template->param(ERRORS  => \@errors);
171 (scalar @$results) and $template->param(TAGLOOP => $results);
172 (scalar @$my_tags) and $template->param(MY_TAGS => $my_tags);
173
174 output_html_with_http_headers $query, $cookie, $template->output;
175