File Coverage

blib/lib/WWW/Tracking/Data/Plugin/Piwik.pm
Criterion Covered Total %
statement 121 124 97.5
branch 27 56 48.2
condition n/a
subroutine 29 29 100.0
pod 0 2 0.0
total 177 211 83.8


line stmt bran cond sub pod time code
1             package WWW::Tracking::Data::Plugin::Piwik;
2              
3 1     1   1135 use strict;
  1         2  
  1         23  
4 1     1   3 use warnings;
  1         1  
  1         35  
5              
6             our $VERSION = '0.05';
7              
8 1     1   3 use WWW::Tracking::Data;
  1         1  
  1         3  
9 1     1   378 use URI::Escape 'uri_escape';
  1         890  
  1         64  
10 1     1   591 use LWP::UserAgent;
  1         27147  
  1         26  
11 1     1   5 use URI;
  1         1  
  1         16  
12 1     1   355 use URI::QueryParam;
  1         495  
  1         23  
13 1     1   5 use Carp::Clan 'croak';
  1         1  
  1         7  
14 1     1   613 use List::MoreUtils 'natatime';
  1         6658  
  1         5  
15              
16             our $PK_VERSION = 1;
17             our @URL_PAIRS = (
18             'cip' => 'remote_ip', #
19             'cid' => 'visitor_id', #
20             'cdt' => 'timestamp', #
21             'fla' => 'flash_version', #
22             'java' => 'java_version',
23             'qt' => 'quicktime_version',
24             'realp' => 'realplayer_version',
25             'pdf' => 'pdf_support',
26             'wma' => 'mediaplayer_version',
27             'gears' => 'gears_version',
28             'ag' => 'silverlight_version',
29             'h' => 'request_hour',
30             'm' => 'request_minute',
31             's' => 'request_second',
32             'res' => 'screen_resolution',
33             'cookie' => 'cookie_support',
34             'url' => 'full_request_url',
35             'urlref' => 'referer',
36             'action_name' => 'request_uri',
37             );
38              
39             sub _piwik_url {
40 2     2   2 my $class = shift;
41 2         3 my $tracking_data = shift;
42            
43 2         7 my $pk_tracking_data = bless $tracking_data, 'WWW::Tracking::Data::Plugin::Piwik::DataFilter';
44 2         6 my $tracker_account = $pk_tracking_data->_tracking->tracker_account;
45 2         14 my $tracker_url = $pk_tracking_data->_tracking->tracker_url;
46 2 50       13 croak 'no tracker url set'
47             unless $tracker_url;
48 2         10 $tracker_url = URI->new($tracker_url);
49            
50 2         5102 my $tracker_token;
51 2 50       9 if ($tracker_account =~ m/^(\d):(.+)$/) {
52 2         4 $tracker_account = $1;
53 2         3 $tracker_token = $2;
54             }
55            
56 2         10 $tracker_url->query_param('idsite' => $tracker_account);
57 2 50       212 $tracker_url->query_param('token_auth' => $tracker_token)
58             if defined $tracker_token;
59 2         174 $tracker_url->query_param('rec' => 1);
60 2         193 $tracker_url->query_param('apiv' => $PK_VERSION);
61 2         225 $tracker_url->query_param('rand' => $class->_uniq_rand_id);
62            
63 2         273 my $url_pair_it = natatime 2, @URL_PAIRS;
64 2         12 while (my ($param_name, $prop) = $url_pair_it->()) {
65 38         10520 my $value = $pk_tracking_data->$prop;
66 38 50       1890 $tracker_url->query_param($param_name => $value)
67             if defined $value;
68             }
69              
70 2         1019 return $tracker_url->as_string;
71             }
72              
73             sub _uniq_rand_id {
74             return int(rand(0x7fffffff));
75             }
76              
77             1;
78              
79             package WWW::Tracking::Data::Plugin::Piwik::DataFilter;
80              
81 1     1   669 use base 'WWW::Tracking::Data';
  1         1  
  1         78  
82              
83 1     1   752 use DateTime;
  1         294074  
  1         457  
84              
85             sub browser_language {
86 1     1   2 my $self = shift;
87 1         7 my $lang = $self->SUPER::browser_language(@_);
88            
89 1 50       8 return unless $lang;
90 0         0 $lang =~ s/^( [a-zA-Z\-]{2,5} ) .* $/$1/xms; # return only first language that can be either two letter or "en-GB" format
91 0 0       0 return unless $lang;
92 0         0 return $lang;
93             }
94              
95             sub timestamp {
96 2     2   3 my $self = shift;
97 2         10 my $timestamp = $self->SUPER::timestamp(@_);
98            
99 2 50       8 return unless $timestamp;
100 2         17 return DateTime->from_epoch( epoch => $timestamp )->strftime('%Y-%m-%d %H:%M:%S');
101             }
102              
103             sub request_hour {
104 2     2   29 my $self = shift;
105 2         8 my $timestamp = $self->SUPER::timestamp;
106 2 50       10 return unless $timestamp;
107 2         8 return DateTime->from_epoch( epoch => $timestamp )->strftime('%H');
108             }
109              
110             sub request_minute {
111 2     2   3 my $self = shift;
112 2         6 my $timestamp = $self->SUPER::timestamp;
113 2 50       9 return unless $timestamp;
114 2         6 return DateTime->from_epoch( epoch => $timestamp )->strftime('%M');
115             }
116             sub request_second {
117 2     2   4 my $self = shift;
118 2         6 my $timestamp = $self->SUPER::timestamp;
119 2 50       8 return unless $timestamp;
120 2         6 return DateTime->from_epoch( epoch => $timestamp )->strftime('%S');
121             }
122              
123             sub flash_version {
124 2     2   2 my $self = shift;
125 2         9 my $flash_version = $self->SUPER::flash_version(@_);
126            
127 2 50       10 return unless defined $flash_version;
128 2 50       6 return ($flash_version ? 1 : 0);
129             }
130              
131             sub java_version {
132 2     2   3 my $self = shift;
133 2         7 my $java_version = $self->SUPER::java_version(@_);
134            
135 2 50       10 return unless defined $java_version;
136 2 50       4 return ($java_version ? 1 : 0);
137             }
138              
139             sub quicktime_version {
140 2     2   3 my $self = shift;
141 2         8 my $quicktime_version = $self->SUPER::quicktime_version(@_);
142            
143 2 50       10 return unless defined $quicktime_version;
144 2 50       3 return ($quicktime_version ? 1 : 0);
145             }
146              
147             sub realplayer_version {
148 2     2   4 my $self = shift;
149 2         9 my $realplayer_version = $self->SUPER::realplayer_version(@_);
150            
151 2 50       10 return unless defined $realplayer_version;
152 2 50       3 return ($realplayer_version ? 1 : 0);
153             }
154              
155             sub pdf_support {
156 2     2   4 my $self = shift;
157 2         8 my $pdf_support = $self->SUPER::pdf_support(@_);
158            
159 2 50       10 return unless defined $pdf_support;
160 2 50       4 return ($pdf_support ? 1 : 0);
161             }
162              
163             sub mediaplayer_version {
164 2     2   3 my $self = shift;
165 2         8 my $mediaplayer_version = $self->SUPER::mediaplayer_version(@_);
166            
167 2 50       8 return unless defined $mediaplayer_version;
168 2 50       4 return ($mediaplayer_version ? 1 : 0);
169             }
170              
171             sub gears_version {
172 2     2   2 my $self = shift;
173 2         7 my $gears_version = $self->SUPER::gears_version(@_);
174            
175 2 50       9 return unless defined $gears_version;
176 2 50       6 return ($gears_version ? 1 : 0);
177             }
178              
179             sub silverlight_version {
180 2     2   2 my $self = shift;
181 2         9 my $silverlight_version = $self->SUPER::silverlight_version(@_);
182            
183 2 50       10 return unless defined $silverlight_version;
184 2 50       4 return ($silverlight_version ? 1 : 0);
185             }
186              
187             sub visitor_id {
188 2     2   3 my $self = shift;
189 2         6 my $visitor_id = $self->SUPER::visitor_id(@_);
190            
191 2 50       10 return unless defined $visitor_id;
192 2         4 return substr($visitor_id,0,16);
193             }
194              
195             1;
196              
197             package WWW::Tracking::Data;
198              
199 1     1   10 use Carp::Clan 'croak';
  1         1  
  1         7  
200              
201             sub as_piwik {
202 2     2 0 8 my $self = shift;
203            
204 2         13 return WWW::Tracking::Data::Plugin::Piwik->_piwik_url($self);
205             }
206              
207             sub make_tracking_request_piwik {
208 1     1 0 6 my $self = shift;
209            
210 1         7 my $ua = LWP::UserAgent->new;
211 1         2012 $ua->default_header('Accept-Language' => $self->browser_language);
212 1         46 $ua->agent($self->user_agent);
213 1         42 my $ga_output = $ua->get($self->as_piwik);
214              
215 1 50       1201883 croak $ga_output->status_line
216             unless $ga_output->is_success;
217            
218 1         51 return $self;
219             }
220              
221             1;
222              
223             __END__
224              
225             =head1 NAME
226              
227             WWW::Tracking::Data::Plugin::Piwik - serialize to Piwik Tracking URL
228              
229             =head1 SYNOPSIS
230              
231             use WWW::Tracking;
232             use WWW::Tracking::Data::Plugin::Piwik;
233            
234             my $wt = WWW::Tracking->new(
235             'tracker_account' => 5,
236             'tracker_type' => 'piwick',
237             'tracker_url' => 'http://stats.meon.eu/piwik.php',
238             );
239             $wt->from(
240             'headers' => {
241             'headers' => $headers,
242             'request_uri' => $request_uri,
243             'remote_ip' => $remote_ip,
244             'visitor_cookie_name' => $VISITOR_COOKIE_NAME,
245             },
246             );
247            
248             my $visitor_id = $wt->data->visitor_id;
249             my $tracking_cookie = Apache2::Cookie->new(
250             $apache,
251             '-name' => $VISITOR_COOKIE_NAME,
252             '-value' => $visitor_id,
253             '-expires' => '+3M',
254             '-path' => '/',
255             );
256             $tracking_cookie->bake($apache);
257            
258             eval { $wt->make_tracking_request; };
259             if ($@) {
260             $logger->warn('failed to do request tracking - '.$@);
261             }
262              
263             =head1 DESCRIPTION
264              
265             =cut