File Coverage

blib/lib/Plack/Middleware/WURFL/ScientiaMobile.pm
Criterion Covered Total %
statement 34 45 75.5
branch 3 8 37.5
condition n/a
subroutine 11 13 84.6
pod 3 4 75.0
total 51 70 72.8


line stmt bran cond sub pod time code
1             package Plack::Middleware::WURFL::ScientiaMobile;
2              
3 3     3   92765 use Moo;
  3         62264  
  3         20  
4 3     3   9575 use Net::WURFL::ScientiaMobile;
  3         452922  
  3         134  
5 3     3   4690 use Plack::Util;
  3         39442  
  3         103  
6 3     3   28 use Try::Tiny;
  3         6  
  3         287  
7 3     3   19 use URI::Escape qw(uri_escape);
  3         6  
  3         150  
8 3     3   80 use 5.008008;
  3         12  
  3         1976  
9              
10             extends 'Plack::Middleware';
11              
12             our $VERSION = '0.01';
13             sub PSGI_KEY () { q{plack.middleware.wurfl.scientiamobile} }
14             sub CLIENT_CLASS () { q{Net::WURFL::ScientiaMobile} }
15              
16             has 'config' => (
17             is => 'ro',
18             required => 1,
19             isa => sub { die "config must be a hashref!" unless ref $_[0] eq 'HASH' },
20             );
21              
22             has 'client' => (
23             is => 'rw',
24             );
25              
26             sub BUILD {
27 3     3 0 266 my $self = shift;
28 3         61 $self->client(CLIENT_CLASS->new($self->config));
29             }
30              
31             sub call {
32 1     1 1 40137 my $self = shift;
33 1         2 my ($env) = @_;
34            
35             # if we're using a cookie-based cache provider, pass env to it
36 1         13 my $cookie_cache = $self->client->cache->isa('Net::WURFL::ScientiaMobile::Cache::Cookie');
37 1 50       736 $self->client->cache->env($env) if $cookie_cache;
38            
39             # query the ScientiaMobile webservice
40             try {
41 1     1   36 $self->client->detectDevice($env);
42 0         0 $env->{+PSGI_KEY} = $self->client;
43             } catch {
44 1     1   1079604 $env->{+PSGI_KEY} = $_;
45 1         11 };
46            
47 1         17 my $res = $self->app->($env);
48 1 50       8 if ($cookie_cache) {
49             $self->response_cb($res, sub {
50 0     0   0 my $res = shift;
51 0         0 foreach my $cookie_name (%{ $self->client->cache->cookies }) {
  0         0  
52 0         0 push @{$res->[1]}, 'Set-Cookie' => sprintf '%s=%s',
  0         0  
53             uri_escape($cookie_name),
54             uri_escape($self->client->cache->cookies->{$cookie_name});
55             }
56 0         0 });
57             } else {
58 1         8 return $res;
59             }
60             }
61              
62             sub get_from_env {
63 0     0 1 0 my $self_or_class = shift;
64 0         0 my ($env) = @_;
65            
66 0         0 my $obj = $env->{+PSGI_KEY};
67 0 0       0 return (ref $obj eq CLIENT_CLASS) ? $obj : undef;
68             }
69              
70             sub get_error_from_env {
71 1     1 1 14 my $self_or_class = shift;
72 1         2 my ($env) = @_;
73            
74 1         2 my $obj = $env->{+PSGI_KEY};
75 1 50       6 return (ref $obj eq CLIENT_CLASS) ? undef : $obj;
76             }
77              
78             =head1 NAME
79              
80             Plack::Middleware::WURFL::ScientiaMobile - Query the ScientiaMobile webservice in middleware
81              
82             =head1 SYNOPSIS
83              
84             use Plack::Builder;
85             builder {
86             enable 'WURFL::ScientiaMobile', config => {
87             api_key => '...',
88             };
89             $app;
90             };
91              
92             =head1 DESCRIPTION
93              
94             This middleware is intended to act as a bridge between the WURFL ScientiaMobile webservice
95             and PSGI-based web applications. It does two things: it processes each incoming HTTP request
96             through the C method of L and it places the
97             pre-populated ScientiaMobile object inside the C<$env> structure that is passed to your web
98             application.
99             You can easily access it from your web framework of choice and apply your device-specific logic.
100              
101             If you configure the ScientiaMobile object with a C cache provider, the middleware
102             will be smart enough to interact with it for reading and writing cookies.
103              
104             use Plack::Builder;
105             builder {
106             enable 'WURFL::ScientiaMobile', config => {
107             api_key => '...',
108             cache => Net::WURFL::ScientiaMobile::Cache::Cookie->new,
109             };
110             $app;
111             };
112              
113             =head1 ARGUMENTS
114              
115             This middleware accepts the following arguments.
116              
117             =head2 config
118              
119             This argument is required. It must be a hashref containing the configuration options for the
120             L client object. The only required option is C, but check
121             the documentation for L to learn about all possible options.
122              
123             =head1 SUBROUTINES
124              
125             =head2 PSGI_KEY
126              
127             Returns the PSGI C<$env> key under which you'd expect to find either an instance of
128             L (pre-populated with the device capabilities) or an exception
129             object.
130              
131             =head2 get_from_env
132              
133             Given a L C<$env>, returns the L object containing the device
134             capabilities. If the call to C threw an exception instead of succeeding, this method
135             returns undef.
136              
137             For example, in your web application:
138              
139             use Plack::Middleware::WURFL::ScientiaMobile;
140            
141             sub my_handler {
142             ...
143             my $env = ...; # your web framework provides this
144             my $scientiamobile = Plack::Middleware::WURFL::ScientiaMobile->get_from_env($env);
145             if (!$scientiamobile) {
146             my $error = Plack::Middleware::WURFL::ScientiaMobile->get_error_from_env($env);
147             ....
148             }
149             ....
150             }
151              
152             Refer to the documentation of your web framework to learn how to access C<$env>. For example,
153             L provides it in C<$ctx-Erequest-Eenv>, Dancer provides it in Cenv>,
154             L provides it in C<$tx-Ereq-Eenv>.
155              
156             =head2 get_error_from_env
157              
158             Given a L C<$env>, returns the L object representing the failure. If
159             no exception was caught, undef is returned.
160              
161             Refer to the documentation of L for an explanation of possible
162             exceptions.
163              
164             =head1 SEE ALSO
165              
166             L, L, L
167              
168             =head1 AUTHOR
169              
170             Alessandro Ranellucci C<< >>
171              
172             =head1 COPYRIGHT & LICENSE
173              
174             Copyright 2012, ScientiaMobile, Inc.
175              
176             This program is free software; you can redistribute it and/or modify
177             it under the same terms as Perl itself.
178              
179             =cut
180              
181             1;