File Coverage

blib/lib/MasonX/Interp/WithCallbacks.pm
Criterion Covered Total %
statement 47 47 100.0
branch 8 8 100.0
condition 2 3 66.6
subroutine 10 10 100.0
pod 3 3 100.0
total 70 71 98.5


line stmt bran cond sub pod time code
1             package MasonX::Interp::WithCallbacks;
2              
3 8     8   1226336 use strict;
  8         31  
  8         364  
4 8     8   48 use HTML::Mason qw(1.23);
  8         15  
  8         187  
5 8     8   46 use HTML::Mason::Interp;
  8         27  
  8         183  
6 8     8   44 use HTML::Mason::Exceptions ();
  8         11  
  8         148  
7 8     8   8381 use Params::CallbackRequest;
  8         153892  
  8         304  
8              
9 8     8   77 use vars qw($VERSION @ISA);
  8         18  
  8         963  
10             @ISA = qw(HTML::Mason::Interp);
11             $VERSION = '1.19';
12              
13             Params::Validate::validation_options
14             ( on_fail => sub { HTML::Mason::Exception::Params->throw( join '', @_ ) } );
15              
16              
17             use HTML::Mason::MethodMaker(
18 8         86 read_only => [qw(cb_request)],
19             read_write => [qw(comp_path)],
20 8     8   50 );
  8         15  
21              
22             # We'll use this code reference to eval arguments passed in via httpd.conf
23             # PerlSetVar directives.
24             my $eval_directive = { convert => sub {
25             return 1 if ref $_[0]->[0];
26             for (@{$_[0]}) { $_ = eval $_ }
27             return 1;
28             }};
29              
30             __PACKAGE__->valid_params
31             ( default_priority =>
32             { type => Params::Validate::SCALAR,
33             parse => 'string',
34             default => 5,
35             descr => 'Default callback priority'
36             },
37              
38             default_pkg_key =>
39             { type => Params::Validate::SCALAR,
40             parse => 'string',
41             default => 'DEFAULT',
42             descr => 'Default package key'
43             },
44              
45             callbacks =>
46             { type => Params::Validate::ARRAYREF,
47             parse => 'list',
48             optional => 1,
49             callbacks => $eval_directive,
50             descr => 'Callback specifications'
51             },
52              
53             pre_callbacks =>
54             { type => Params::Validate::ARRAYREF,
55             parse => 'list',
56             optional => 1,
57             callbacks => $eval_directive,
58             descr => 'Callbacks to be executed before argument callbacks'
59             },
60              
61             post_callbacks =>
62             { type => Params::Validate::ARRAYREF,
63             parse => 'list',
64             optional => 1,
65             callbacks => $eval_directive,
66             descr => 'Callbacks to be executed after argument callbacks'
67             },
68              
69             cb_classes =>
70             { type => Params::Validate::ARRAYREF | Params::Validate::SCALAR,
71             parse => 'list',
72             optional => 1,
73             descr => 'List of calback classes from which to load callbacks'
74             },
75              
76             ignore_nulls =>
77             { type => Params::Validate::BOOLEAN,
78             parse => 'boolean',
79             default => 0,
80             descr => 'Execute callbacks with null values'
81             },
82              
83             cb_exception_handler =>
84             { type => Params::Validate::CODEREF,
85             parse => 'code',
86             optional => 1,
87             descr => 'Callback execution exception handler'
88             },
89             );
90              
91              
92             sub new {
93 20     20 1 57621 my $class = shift;
94 20         205 my $self = $class->SUPER::new(@_);
95             # This causes everything to be validated twice, but it shouldn't matter
96             # much, since interp objects won't be created very often.
97 20         113627 my $exh = delete $self->{cb_exception_handler};
98 160 100       715 $self->{cb_request} = Params::CallbackRequest->new
99             ( leave_notes => 1,
100             ($exh ? (exception_handler => $exh) : ()),
101 20         128 map { $self->{$_} ? ($_ => delete $self->{$_}) : () }
102 20 100       96 keys %{ __PACKAGE__->valid_params }
103             );
104 15         3997 $self;
105             }
106              
107             sub make_request {
108 112     112 1 94463 my ($self, %p) = @_;
109             # We have to grab the parameters and copy them into a hash.
110 112         183 my %params = @{$p{args}};
  112         451  
111 112         273 $self->{comp_path} = $p{comp};
112              
113             # Grab the apache request object, if it exists.
114 112   66     834 my $apache_req = $p{apache_req}
115             || $self->delayed_object_params('request', 'apache_req')
116             || $self->delayed_object_params('request', 'cgi_request');
117              
118             # Execute the callbacks.
119 112 100       3012 my $ret = $self->{cb_request}->request(
120             \%params,
121             requester => $self,
122             $apache_req ? ( apache_req => $apache_req ) : (),
123             );
124              
125             # Abort the request if that's what the callbacks want.
126 102 100       145663 unless (ref $ret) {
127 7         43 $self->{cb_request}->clear_notes;
128 7         100 HTML::Mason::Exception::Abort->throw(
129             error => 'Callback->abort was called',
130             aborted_value => $ret,
131             );
132             }
133              
134             # Copy the parameters back -- too much copying!
135 95         395 $p{args} = [%params];
136 95         251 $p{comp} = $self->{comp_path};
137              
138             # Get the request, copy the notes, and continue.
139 95         526 my $req = $self->SUPER::make_request(%p);
140             # Should I use the same reference?
141 94         88443 %{$req->notes} = %{$self->{cb_request}->notes};
  94         750  
  94         637  
142 94         1690 return $req;
143             }
144              
145             # We override this method in order to clear out all the callback notes
146             # at the end of the Mason request.
147             sub purge_code_cache {
148 95     95 1 31800 my $self = shift;
149 95         415 $self->{cb_request}->clear_notes;
150 95         1073 $self->SUPER::purge_code_cache;
151             }
152              
153             1;
154             __END__