File Coverage

blib/lib/WWW/Tracking/Data/Plugin/GoogleAnalytics.pm
Criterion Covered Total %
statement 55 55 100.0
branch 11 16 68.7
condition n/a
subroutine 15 15 100.0
pod 0 2 0.0
total 81 88 92.0


line stmt bran cond sub pod time code
1             package WWW::Tracking::Data::Plugin::GoogleAnalytics;
2              
3 1     1   1172 use strict;
  1         1  
  1         25  
4 1     1   3 use warnings;
  1         1  
  1         37  
5              
6             our $VERSION = '0.05';
7              
8 1     1   4 use WWW::Tracking::Data;
  1         1  
  1         5  
9 1     1   393 use URI::Escape 'uri_escape';
  1         916  
  1         46  
10 1     1   562 use LWP::UserAgent;
  1         27958  
  1         223  
11              
12             our $UTM_GIF_LOCATION = 'http://www.google-analytics.com/__utm.gif';
13             our $GA_VERSION = '4.4sp';
14             our @URL_PAIRS = (
15             'utmhn' => 'hostname', # Host Name, which is a URL-encoded string.
16             'utmp' => 'request_uri', # Page request of the current page.
17             'utmr' => 'referer', # Referral, complete URL.
18             'utmvid' => 'visitor_id', #
19             'utmip' => 'remote_ip', #
20             'utmcs' => 'encoding', # Language encoding for the browser. Some browsers don't set this, in which case it is set to "-"
21             'utmul' => 'browser_language', # Browser language.
22             'utmje' => 'java_version', # Indicates if browser is Java-enabled. 1 is true.
23             'utmsc' => 'screen_color_depth', # Screen color depth
24             'utmsr' => 'screen_resolution', # Screen resolution
25             'utmfl' => 'flash_version', # Flash Version
26             );
27              
28             sub _map2(&@){
29 4     4   40 my $code = shift;
30 4         16 map $code->( shift, shift ), 0 .. $#_/2
31             }
32              
33             sub _utm_url {
34 4     4   5 my $class = shift;
35 4         5 my $tracking_data = shift;
36            
37 4         10 my $ga_tracking_data = bless $tracking_data, 'WWW::Tracking::Data::Plugin::GoogleAnalytics::DataFilter';
38 4         11 my $tracker_account = $ga_tracking_data->_tracking->tracker_account;
39              
40             return
41             $UTM_GIF_LOCATION
42             .'?'
43             .'utmwv='.$GA_VERSION
44             .'&utmac='.$tracker_account # Account String. Appears on all requests.
45             .'&utmn='.$class->_uniq_gif_id # Unique ID generated for each GIF request to prevent caching of the GIF image.
46             .'&utmcc=__utma%3D999.'.substr($ga_tracking_data->visitor_id,0,16).'.999.999.999.1%3B' # Cookie values. This request parameter sends all the cookies requested from the page.
47             .join(
48             '',
49             _map2 {
50 44     44   380 my $prop = $_[1];
51 44         91 my $value = $ga_tracking_data->$prop;
52 44 100       163 (defined $value ? '&'.$_[0].'='.uri_escape($ga_tracking_data->$prop) : ())
53             }
54             @URL_PAIRS
55 4         34 )
56             ;
57             }
58              
59             sub _uniq_gif_id {
60             return int(rand(0x7fffffff));
61             }
62              
63             1;
64              
65             package WWW::Tracking::Data::Plugin::GoogleAnalytics::DataFilter;
66              
67 1     1   6 use base 'WWW::Tracking::Data';
  1         1  
  1         199  
68              
69             sub browser_language {
70 8     8   9 my $self = shift;
71 8         22 my $lang = $self->SUPER::browser_language(@_);
72            
73 8 100       31 return unless $lang;
74 5         15 $lang =~ s/^( [a-zA-Z\-]{2,5} ) .* $/$1/xms; # return only first language that can be either two letter or "en-GB" format
75 5 50       9 return unless $lang;
76 5         9 return $lang;
77             }
78              
79             sub remote_ip {
80 8     8   6 my $self = shift;
81 8         18 my $ip = $self->SUPER::remote_ip(@_);
82            
83 8 50       27 return unless $ip;
84 8 50       32 return unless $ip =~ m/^( (?: \d{1,3} [.] ){3} ) \d{1,3} $/xms; # capture only first 3 numbers from ip
85 8         20 return $1.'0';
86             }
87              
88             sub java_version {
89 6     6   7 my $self = shift;
90 6         13 my $java_version = $self->SUPER::java_version(@_);
91            
92 6 100       19 return unless defined $java_version;
93 4 50       9 return ($java_version ? 1 : 0);
94             }
95              
96             1;
97              
98             package WWW::Tracking::Data;
99              
100 1     1   4 use Carp::Clan 'croak';
  1         1  
  1         6  
101              
102             sub as_ga {
103 4     4 0 14 my $self = shift;
104            
105 4         17 return WWW::Tracking::Data::Plugin::GoogleAnalytics->_utm_url($self);
106             }
107              
108             sub make_tracking_request_ga {
109 2     2 0 8 my $self = shift;
110            
111 2         11 my $ua = LWP::UserAgent->new;
112 2         2054 $ua->default_header('Accept-Language' => $self->browser_language);
113 2         72 $ua->agent($self->user_agent);
114 2         91 my $ga_output = $ua->get($self->as_ga);
115              
116 2 50       110553 croak $ga_output->status_line
117             unless $ga_output->is_success;
118            
119 2         132 return $self;
120             }
121              
122             1;
123              
124             __END__
125              
126             =head1 NAME
127              
128             WWW::Tracking::Data::Plugin::GoogleAnalytics - serialize to Google Analytics URL
129              
130             =head1 SYNOPSIS
131              
132             use WWW::Tracking;
133             use WWW::Tracking::Data::Plugin::GoogleAnalytics;
134            
135             my $wt = WWW::Tracking->new(
136             'tracker_account' => 'MO-9226801-5',
137             'tracker_type' => 'ga',
138             );
139             $wt->from(
140             'headers' => {
141             'headers' => $headers,
142             'request_uri' => $request_uri,
143             'remote_ip' => $remote_ip,
144             'visitor_cookie_name' => $VISITOR_COOKIE_NAME,
145             },
146             );
147            
148             my $visitor_id = $wt->data->visitor_id;
149             my $tracking_cookie = Apache2::Cookie->new(
150             $apache,
151             '-name' => $VISITOR_COOKIE_NAME,
152             '-value' => $visitor_id,
153             '-expires' => '+3M',
154             '-path' => '/',
155             );
156             $tracking_cookie->bake($apache);
157            
158             eval { $wt->make_tracking_request; };
159             if ($@) {
160             $logger->warn('failed to do request tracking - '.$@);
161             }
162              
163             =head1 DESCRIPTION
164              
165             =cut