1 # Copyright 2002-2007 Interchange Development Group and others
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version. See the LICENSE file for details.
8 # $Id: traffic_report.coretag,v 1.6 2007-03-30 23:40:54 pajamian Exp $
10 UserTag traffic-report Order save
11 UserTag traffic-report addAttr
12 UserTag traffic-report Version $Revision: 1.6 $
13 UserTag traffic-report Routine <<EOR
15 my ($save, $opt) = @_;
20 date => errmsg('Date'),
21 affiliate => errmsg('Affiliate'),
22 campaign => errmsg('Campaign'),
23 visits => errmsg('Visits'),
24 hits => errmsg('Hits'),
25 pages => errmsg('Pages'),
26 views => errmsg('Prod. views'),
27 incart => errmsg('Items in cart'),
28 orders => errmsg('Orders'),
38 if(ref $opt->{header}) {
39 for(keys %{$opt->{header}}) {
40 $header{$_} = errmsg($opt->{header}{$_});
44 my $cols = $opt->{show} || 'date affiliate visits hits pages views incart orders';
45 my @cols = grep /\w/, split /[\0,\s]+/, $cols;
46 my $numcols = scalar(@cols);
49 <TABLE width="90%" border=0 cellpadding=0 cellspacing=0>
50 <tr class=rborder height=1><td colspan=8></td></tr>
54 push @out, "<TD VALIGN=top>$header{$_}</td>";
59 <tr class=rborder height=1><td colspan=8></td></tr>
62 my $file = $Vend::Cfg->{TrackFile};
64 push @out, "<tr><td colspan=$numcols class=error>No traffic statistics found</td></tr></table>";
68 unless(open REPORT, "< $file") {
69 push @out, "<tr><td colspan=$numcols class=error>Cannot open file $file</td></tr></table>";
73 my $affiliate = $opt->{affiliate} || $CGI::values{affiliate};
74 my $begin_date = $opt->{begin_date} || $CGI::values{ui_begin_date};
75 my $end_date = $opt->{end_date} || $CGI::values{ui_end_date};
76 my $Tag = new Vend::Tags;
79 $begin_date = filter_value('date_change', $begin_date);
80 look(\*REPORT, $begin_date) if $begin_date;
83 $end_date = filter_value('date_change', $end_date)
101 my $timeout = $::Variable->{VISIT_TIMEOUT} || (30 * 10);
103 my $by_day = $opt->{by_day} || $CGI::values{ui_by_day};
105 $len = $by_day ? 8 : 6;
109 my $break_check = sub {
110 if(! defined($prev)) {
114 if ($end_date and $_[0] gt $end_date) {
118 return if $_[0] eq $prev;
126 my $interval_count = 0;
127 my $interval_total = 0;
128 my $max_interval = 0;
129 my $min_interval = 9999999;
135 my %action_by_period;
138 my %action_by_visit_number;
139 my %actions_per_visit_boolean;
146 my %session_by_order;
149 my %visit_by_aff_by_day;
150 my %visit_by_aff_by_period;
154 my %visit_by_session;
162 ## To fudge around break
170 ## To fudge around break, so that we can break then recall
171 ## the line where we broke
177 my $line = [ split /\t/, $_ , 7];
179 my $per = substr($line->[0], 0, $len);
185 next if $affiliate and $line->[5] ne $affiliate;
189 $hits_by_period{$per}++;
190 $hits_by_day{$line->[0]}++;
191 $hits_by_session{$line->[1]}++
192 or $update_visit = 1;
194 $interval = $line->[4] - $last_access{$line->[1]}
195 if $last_access{$line->[1]};
197 $max_interval = $interval
198 if $interval > $max_interval;
199 $min_interval = $interval
200 if $interval < $min_interval;
201 $interval_total += $interval;
203 $update_visit = 1 if $interval > $timeout;
205 $last_access{$line->[1]} = $line->[4];
209 $visit_number = "$line->[1]:" . $visit_by_session{$line->[1]}++;
210 $visit_by_period{$per}++;
211 $visit_by_day{$line->[0]}++;
212 $visit_by_user{$line->[2]}++;
213 $visit_by_ip{$line->[3]}++;
214 $visit_by_aff{$line->[5]}++;
215 $visit_by_aff_by_period{$per}{$line->[5]}++;
216 $visit_by_aff_by_day{$line->[0]}{$line->[5]}++;
219 # Leave this at & instead of UrlJoiner because of Vend::Track
220 my (@items) = split /(?:^|&)([A-Z]+)=/, $line->[6];
222 #::logDebug("items = " . ::uneval(\@items)) if $line->[6] =~ / \& /;
224 my($tag, $val) = splice(@items, 0, 2);
225 $action_by_visit{$tag}++
226 unless $action_by_visit_number{$visit_number}{$tag}++;
227 $action_by_tag{$tag}{$val}++;
228 $action_by_aff{$line->[5]}{$tag}++;
229 $action_by_period{$per}{$tag}++;
230 $action_by_day{$line->[0]}{$tag}++;
233 ## To fudge around break
240 #::logDebug("action_by_visit=" . ::uneval(\%action_by_visit));
241 foreach my $one (sort keys %visit_by_period) {
242 my ($yr, $mon, $day) = $one =~ /(\d\d\d\d)(\d\d)(\d\d)?/;
245 push @out, "<TR class=rnorm>\n";
246 $date = $day ? "$names{$mon} $day, $yr" : "$names{$mon} $yr";
247 $output{date} = <<EOF;
252 my (@number) = grep /\S/, keys %{ $visit_by_aff_by_period{$one} };
253 my $count = scalar(@number);
254 $output{affiliate} = <<EOF;
255 <TD VALIGN="top" ALIGN=CENTER>
260 $output{visits} = <<EOF;
261 <TD VALIGN="top" ALIGN=CENTER>
262 $visit_by_period{$one}
266 $output{hits} = <<EOF;
267 <TD VALIGN="top" ALIGN=CENTER>
268 $hits_by_period{$one}
271 for(qw/ VIEWPAGE VIEWPROD ADDITEM ORDER /) {
272 $count = $action_by_period{$one}{$_} || 0;
274 $pct = $action_by_visit{$_} / $visit_by_period{$one} * 100
275 if $visit_by_period{$one};
276 $pct = $pct <= 0 ? '' : sprintf( "<FONT SIZE=1><BR>%.2f%%</FONT>", $pct);
277 $output{$hmap{$_}} = <<EOF;
278 <TD VALIGN="top" ALIGN=CENTER>
284 push @out, $output{$_};
289 redo BREAK unless $done or eof(REPORT);
292 <tr class=rborder height=1><td colspan=8></td></tr>
295 return join "\n", @out;