spelling fixes and more docs
[catagits/Catalyst-Runtime.git] / lib / Catalyst / ActionRole / ConsumesContent.pm
CommitLineData
3e0665e4 1package Catalyst::ActionRole::ConsumesContent;
2
3use Moose::Role;
4
2d802c4a 5requires 'match', 'match_captures', 'list_extra_info';
3e0665e4 6
7has allowed_content_types => (
8 is=>'ro',
9 required=>1,
10 lazy=>1,
11 isa=>'ArrayRef',
3e0665e4 12 builder=>'_build_allowed_content_types');
13
4737c6c7 14has normalized => (
15 is=>'ro',
16 required=>1,
17 lazy=>1,
18 isa=>'HashRef',
19 builder=>'_build_normalized');
20
21
22sub _build_normalized {
23 return +{
24 JSON => 'application/json',
25 JS => 'application/javascript',
26 PERL => 'application/perl',
27 HTML => 'text/html',
28 XML => 'text/XML',
29 Plain => 'text/plain',
30 UrlEncoded => 'application/x-www-form-urlencoded',
31 Multipart => 'multipart/form-data',
32 HTMLForm => ['application/x-www-form-urlencoded','multipart/form-data'],
33 };
34}
35
36sub _build_allowed_content_types {
37 my $self = shift;
e72a3cd6 38 my @proto = map {split ',', $_ } @{$self->attributes->{Consumes}};
39 my @converted = map {
4737c6c7 40 if(my $normalized = $self->normalized->{$_}) {
41 ref $normalized ? @$normalized : ($normalized);
42 } else {
43 $_;
44 }
45 } @proto;
e72a3cd6 46
47 return \@converted;
4737c6c7 48}
3e0665e4 49
50around ['match','match_captures'] => sub {
51 my ($orig, $self, $ctx, @args) = @_;
52 if(my $content_type = $ctx->req->content_type) {
53 return 0 unless $self->can_consume($content_type);
54 }
55 return $self->$orig($ctx, @args);
56};
57
58sub can_consume {
59 my ($self, $request_content_type) = @_;
60 my @matches = grep { lc($_) eq lc($request_content_type) }
e72a3cd6 61 @{$self->allowed_content_types};
3e0665e4 62 return @matches ? 1:0;
63}
64
e72a3cd6 65around 'list_extra_info' => sub {
66 my ($orig, $self, @args) = @_;
67 return {
68 %{ $self->$orig(@args) },
69 CONSUMES => $self->allowed_content_types,
70 };
71};
72
3e0665e4 731;
74
75=head1 NAME
76
77Catalyst::ActionRole::ConsumesContent - Match on HTTP Request Content-Type
78
79=head1 SYNOPSIS
80
81 package MyApp::Web::Controller::MyController;
82
83 use base 'Catalyst::Controller';
84
85 sub start : POST Chained('/') CaptureArg(0) { ... }
86
87 sub is_json : Chained('start') Consumes('application/json') { ... }
88 sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
89 sub is_multipart : Chained('start') Consumes('multipart/form-data') { ... }
90
91 ## Alternatively, for common types...
92
4737c6c7 93 sub is_json : Chained('start') Consume(JSON) { ... }
68c372d1 94 sub is_urlencoded : Chained('start') Consumes(UrlEncoded) { ... }
95 sub is_multipart : Chained('start') Consumes(Multipart) { ... }
3e0665e4 96
97 ## Or allow more than one type
98
99 sub is_more_than_one
100 : Chained('start')
101 : Consumes('application/x-www-form-urlencoded')
102 : Consumes('multipart/form-data')
103 {
104 ## ...
105 }
106
107 1;
108
109=head1 DESCRIPTION
110
111This is an action role that lets your L<Catalyst::Action> match on the content
112type of the incoming request.
113
114Generally when there's a PUT or POST request, there's a request content body
115with a matching MIME content type. Commonly this will be one of the types
116used with classic HTML forms ('application/x-www-form-urlencoded' for example)
117but there's nothing stopping you specifying any valid content type.
118
119For matching purposes, we match strings but the casing is insensitive.
120
121=head1 REQUIRES
122
123This role requires the following methods in the consuming class.
124
125=head2 match
126
127=head2 match_captures
128
129Returns 1 if the action matches the existing request and zero if not.
130
131=head1 METHODS
132
133This role defines the following methods
134
135=head2 match
136
137=head2 match_captures
138
139Around method modifier that return 1 if the request content type matches one of the
140allowed content types (see L</http_methods>) and zero otherwise.
141
142=head2 allowed_content_types
143
144An array of strings that are the allowed content types for matching this action.
145
69a62684 146=head2 can_consume
147
148Boolean. Does the current request match content type with what this actionrole
149can consume?
150
2d802c4a 151=head2 list_extra_info
152
153Add the accepted content type to the debug screen.
154
3e0665e4 155=head1 AUTHORS
156
157Catalyst Contributors, see Catalyst.pm
158
159=head1 COPYRIGHT
160
161This library is free software. You can redistribute it and/or modify it under
162the same terms as Perl itself.
163
164=cut