line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Catalyst::Plugin::StructuredParameters; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
3503
|
use Moose::Role; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
9
|
|
4
|
1
|
|
|
1
|
|
6232
|
use Scalar::Util; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
274
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
1
|
1506
|
sub structured_body { return shift->req->structured_body(@_) } |
7
|
1
|
|
|
1
|
1
|
1008
|
sub structured_data { return shift->req->structured_data(@_) } |
8
|
2
|
|
|
2
|
1
|
79714
|
sub structured_query { return shift->req->structured_query(@_) } |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub isa_structured_parameter_exception { |
11
|
0
|
|
|
0
|
1
|
|
my ($self, $obj) = @_; |
12
|
0
|
0
|
|
|
|
|
return 0 unless Scalar::Util::blessed($obj); |
13
|
0
|
0
|
|
|
|
|
return $obj->isa('Catalyst::Exception::StructuredParameter') ? 1:0; |
14
|
|
|
|
|
|
|
} |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
around request_class_traits => sub { |
17
|
|
|
|
|
|
|
my ($orig, $self, @args) = @_; |
18
|
|
|
|
|
|
|
my $traits = $self->$orig(@args); |
19
|
|
|
|
|
|
|
return [ @{$traits||[]}, 'Catalyst::TraitFor::Request::StructuredParameters' ]; |
20
|
|
|
|
|
|
|
}; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
1; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 NAME |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
Catalyst::Plugin::StructuredParameters - Plug to add the structured parameter request trait plus proxy methods |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 SYNOPSIS |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
package MyApp; |
31
|
|
|
|
|
|
|
use Catalyst 'StructuredParameters'; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
MyApp->setup; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
package MyApp::Controller::Root; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
sub body :Local { |
38
|
|
|
|
|
|
|
my ($self, $c) = @_; |
39
|
|
|
|
|
|
|
my %clean = $c->structured_body |
40
|
|
|
|
|
|
|
->permitted(['person'], +{'email' => []}) |
41
|
|
|
|
|
|
|
->namespace(['person']) |
42
|
|
|
|
|
|
|
->permitted( |
43
|
|
|
|
|
|
|
'name', |
44
|
|
|
|
|
|
|
'age', |
45
|
|
|
|
|
|
|
'address' => ['street' => ['number', 'zip'], |
46
|
|
|
|
|
|
|
+{'credit_cards' => [ |
47
|
|
|
|
|
|
|
'number', |
48
|
|
|
|
|
|
|
'exp' => [qw/year month day/], |
49
|
|
|
|
|
|
|
]}, |
50
|
|
|
|
|
|
|
)->to_hash; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
## Do something with the sanitized body parameters |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
## Don't forget to add code to handle any exceptions |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub end :Action { |
58
|
|
|
|
|
|
|
my ($self, $c) = @_; |
59
|
|
|
|
|
|
|
if(my $error = $c->last_error) { |
60
|
|
|
|
|
|
|
$c->clear_errors; ## Clear the error stack unless you want the default Catalyst error |
61
|
|
|
|
|
|
|
if($c->isa_strong_parameter_exception($error)) { |
62
|
|
|
|
|
|
|
## Something here like return a Bad Request 4xx view or similar. |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
## Alternatively handle with L<CatalystX::Errors> (don't forget to add the plugin to your |
68
|
|
|
|
|
|
|
## application class.) |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub end :Action Does(RenderErrors) { } |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
You should review L<Catalyst::TraitFor::Request::StructuredParameters> for a more detailed SYNOPSIS and |
73
|
|
|
|
|
|
|
explanation of how all this works. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=head1 DESCRIPTION |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
This plugin will add in the L<Catalyst::TraitFor::Request::StructuredParameters> request class trait |
78
|
|
|
|
|
|
|
and proxy some of its methods to the context. You might find this a bit less typing. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
All the main documentation is in L<Catalyst::TraitFor::Request::StructuredParameters>. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
NOTE: This plugin only works with For L<Catalyst> v5.90090 or greater. If you must use an older |
83
|
|
|
|
|
|
|
version of L<Catalyst> you'll need to use the workaround described in the SYNOPSIS of |
84
|
|
|
|
|
|
|
L<Catalyst::TraitFor::Request::StructuredParameters>. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=head1 METHODS |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
This role defines the following methods: |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head2 structured_body |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 structured_data |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=head2 structured_query |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
These just proxy to the same methods under the L<Catalyst::Request> object. |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=head2 isa_structured_parameter_exception |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
This is just a convenience method that returns true if a possible exception is both a blessed |
101
|
|
|
|
|
|
|
object and ISA L<Catalyst::Exception::StructuredParameter>. Since you need to add checking for |
102
|
|
|
|
|
|
|
this everytime I added this method to save a bit of trouble. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 AUTHOR |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
See L<Catalyst::TraitFor::Request::StructuredParameters> |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head1 SEE ALSO |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
L<Catalyst>, L<Catalyst::TraitFor::Request::StructuredParameters> |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
See L<Catalyst::TraitFor::Request::StructuredParameters> |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |