9638a2d7a2d0dd544998d376d9a1e39ae783a4a6
[catagits/Catalyst-Runtime.git] / lib / Catalyst / ActionRole / ConsumesContent.pm
1 package Catalyst::ActionRole::ConsumesContent;
2
3 use Moose::Role;
4
5 requires 'match', 'match_captures';
6
7 has allowed_content_types => (
8   is=>'ro',
9   required=>1,
10   lazy=>1,
11   isa=>'ArrayRef',
12   auto_deref=>1,
13   builder=>'_build_allowed_content_types');
14
15 sub _build_allowed_content_types { shift->attributes->{Consumes} }
16
17 around ['match','match_captures'] => sub {
18     my ($orig, $self, $ctx, @args) = @_;
19     if(my $content_type = $ctx->req->content_type) {
20         return 0 unless $self->can_consume($content_type);
21     }
22     return $self->$orig($ctx, @args);
23 };
24
25 sub can_consume {
26     my ($self, $request_content_type) = @_;
27     my @matches = grep { lc($_) eq lc($request_content_type) }
28       $self->allowed_content_types;
29     return @matches ? 1:0;
30 }
31
32 1;
33
34 =head1 NAME
35
36 Catalyst::ActionRole::ConsumesContent - Match on HTTP Request Content-Type
37
38 =head1 SYNOPSIS
39
40     package MyApp::Web::Controller::MyController;
41
42     use base 'Catalyst::Controller';
43
44     sub start : POST Chained('/') CaptureArg(0) { ... }
45
46       sub is_json       : Chained('start') Consumes('application/json') { ... }
47       sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
48       sub is_multipart  : Chained('start') Consumes('multipart/form-data') { ... }
49       
50       ## Alternatively, for common types...
51
52       sub is_json       : Chained('start') JSON { ... }
53       sub is_urlencoded : Chained('start') URLEncoded { ... }
54       sub is_multipart  : Chained('start') FormData { ... }
55
56       ## Or allow more than one type
57       
58       sub is_more_than_one
59         : Chained('start')
60         : Consumes('application/x-www-form-urlencoded')
61         : Consumes('multipart/form-data')
62       {
63         ## ... 
64       }
65
66       1;
67
68 =head1 DESCRIPTION
69
70 This is an action role that lets your L<Catalyst::Action> match on the content
71 type of the incoming request.  
72
73 Generally when there's a PUT or POST request, there's a request content body
74 with a matching MIME content type.  Commonly this will be one of the types
75 used with classic HTML forms ('application/x-www-form-urlencoded' for example)
76 but there's nothing stopping you specifying any valid content type.
77
78 For matching purposes, we match strings but the casing is insensitive.
79
80 =head1 REQUIRES
81
82 This role requires the following methods in the consuming class.
83
84 =head2 match
85
86 =head2 match_captures
87
88 Returns 1 if the action matches the existing request and zero if not.
89
90 =head1 METHODS
91
92 This role defines the following methods
93
94 =head2 match
95
96 =head2 match_captures
97
98 Around method modifier that return 1 if the request content type matches one of the
99 allowed content types (see L</http_methods>) and zero otherwise.
100
101 =head2 allowed_content_types
102
103 An array of strings that are the allowed content types for matching this action.
104
105 =head1 AUTHORS
106
107 Catalyst Contributors, see Catalyst.pm
108
109 =head1 COPYRIGHT
110
111 This library is free software. You can redistribute it and/or modify it under
112 the same terms as Perl itself.
113
114 =cut