|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package CatalystX::RequestModel::DoesRequestModel;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
3137
 | 
 use Moo::Role;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
4
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
23347
 | 
 use Scalar::Util;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
362
 | 
    | 
| 
5
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
2578
 | 
 use CatalystX::RequestModel::Utils::BadRequest;  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2202
 | 
    | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8977
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has ctx => (is=>'ro');  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has current_namespace => (is=>'ro', predicate=>'has_current_namespace');  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has current_parser => (is=>'ro', predicate=>'has_current_parser');  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has catalyst_component_name => (is=>'ro');  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub namespace {  | 
| 
13
 | 
51
 | 
 
 | 
 
 | 
  
51
  
 | 
 
 | 
195
 | 
   my ($class_or_self, @data) = @_;  | 
| 
14
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
170
 | 
   my $class = ref($class_or_self) ? ref($class_or_self) : $class_or_self;  | 
| 
15
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
194
 | 
   if(@data) {  | 
| 
16
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     @data = map { split /\./, $_ } @data;  | 
| 
 
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
    | 
| 
17
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
85
 | 
     CatalystX::RequestModel::_add_metadata($class, 'namespace', @data);  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
20
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
427
 | 
   return $class_or_self->namespace_metadata if $class_or_self->can('namespace_metadata');  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub content_in {  | 
| 
24
 | 
51
 | 
 
 | 
 
 | 
  
51
  
 | 
 
 | 
132
 | 
   my ($class_or_self, $ct) = @_;  | 
| 
25
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
176
 | 
   my $class = ref($class_or_self) ? ref($class_or_self) : $class_or_self;  | 
| 
26
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
150
 | 
   CatalystX::RequestModel::_add_metadata($class, 'content_in', $ct) if $ct;  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
51
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
330
 | 
   if($class_or_self->can('content_in_metadata')) {  | 
| 
29
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     my ($ct) = $class_or_self->content_in_metadata;  # needed because this returns an array but we only want the first one  | 
| 
30
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
63
 | 
     return $ct if $ct;  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_content_in {  | 
| 
35
 | 
45
 | 
 
 | 
 
 | 
  
45
  
 | 
  
0
  
 | 
890
 | 
   my $self = shift;  | 
| 
36
 | 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
186
 | 
   my $ct = $self->content_in;  | 
| 
37
 | 
45
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
168
 | 
   return lc($ct) if $ct;  | 
| 
38
 | 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
189
 | 
   return 'body';  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub content_type {  | 
| 
42
 | 
63
 | 
 
 | 
 
 | 
  
63
  
 | 
 
 | 
274
 | 
   my ($class_or_self, @ct) = @_;  | 
| 
43
 | 
63
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
265
 | 
   my $class = ref($class_or_self) ? ref($class_or_self) : $class_or_self;  | 
| 
44
 | 
63
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
321
 | 
   CatalystX::RequestModel::_add_metadata($class, 'content_type', @ct) if @ct;  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
63
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
392
 | 
   if($class_or_self->can('content_type_metadata')) {  | 
| 
47
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
224
 | 
     my (@ct) = $class_or_self->content_type_metadata;  # needed because this returns an array but we only want the first onei  | 
| 
48
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
223
 | 
     return @ct;  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub property {  | 
| 
53
 | 
354
 | 
 
 | 
 
 | 
  
354
  
 | 
 
 | 
948
 | 
   my ($class_or_self, $attr, $data_proto, $options) = @_;  | 
| 
54
 | 
354
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
861
 | 
   my $class = ref($class_or_self) ? ref($class_or_self) : $class_or_self;  | 
| 
55
 | 
354
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
863
 | 
   if(defined $data_proto) {  | 
| 
56
 | 
354
 | 
  
 50
  
 | 
  
 50
  
 | 
 
 | 
 
 | 
1150
 | 
     my $data = (ref($data_proto)||'') eq 'HASH' ? $data_proto : +{ name => $attr };  | 
| 
57
 | 
354
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
981
 | 
     $data->{name} = $attr unless exists($data->{name});  | 
| 
58
 | 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1570
 | 
     CatalystX::RequestModel::_add_metadata($class, 'property_data', +{$attr => $data});  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub properties {  | 
| 
63
 | 
63
 | 
 
 | 
 
 | 
  
63
  
 | 
 
 | 
135
 | 
   my ($class_or_self, @data) = @_;  | 
| 
64
 | 
63
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
209
 | 
   my $class = ref($class_or_self) ? ref($class_or_self) : $class_or_self;  | 
| 
65
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
180
 | 
   while(@data) {  | 
| 
66
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $attr = shift(@data);  | 
| 
67
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my $data = (ref($data[0])||'') eq 'HASH' ? shift(@data) : +{ name => $attr };  | 
| 
68
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $data->{name} = $attr unless exists($data->{name});  | 
| 
69
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     CatalystX::RequestModel::_add_metadata($class, 'property_data', +{$attr => $data});  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
72
 | 
63
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
366
 | 
   return $class_or_self->property_data_metadata if $class_or_self->can('property_data_metadata');  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub COMPONENT {  | 
| 
76
 | 
84
 | 
 
 | 
 
 | 
  
84
  
 | 
  
0
  
 | 
927651
 | 
   my ($class, $app, $args) = @_;  | 
| 
77
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
790
 | 
   $args = $class->merge_config_hashes($class->config, $args);  | 
| 
78
 | 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15983
 | 
   return bless $args, $class;  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ## TODO handle if we are wrapping a model that already does ACCEPT_CONTEXT  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub ACCEPT_CONTEXT {  | 
| 
83
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
0
  
 | 
2173
 | 
   my $self = shift;  | 
| 
84
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
   my $c = shift;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
240
 | 
   my %args = (%$self, @_);    | 
| 
87
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
146
 | 
   my %request_args = $self->parse_content_body($c, %args);  | 
| 
88
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
197
 | 
   my %init_args = (%args, %request_args, ctx=>$c);  | 
| 
89
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
   my $class = ref($self);  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
91
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
142
 | 
   return my $request_model = $self->build_request_model($c, $class, %init_args);  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub build_request_model {  | 
| 
95
 | 
32
 | 
 
 | 
 
 | 
  
32
  
 | 
  
0
  
 | 
137
 | 
   my ($self, $c, $class, %init_args) = @_;  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $request_model = eval {  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $class->new(%init_args)  | 
| 
98
 | 
32
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
77
 | 
   } || do {   | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     CatalystX::RequestModel::Utils::BadRequest->throw(class=>$class, error_trace=>$@);  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10088
 | 
   return $request_model;  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub parse_content_body {  | 
| 
106
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
0
  
 | 
108
 | 
   my ($self, $c, %args) = @_;  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
108
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
159
 | 
   my @rules = $self->properties;  | 
| 
109
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
151
 | 
   my @ns = $self->get_namespace(%args);              | 
| 
110
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
121
 | 
   my $parser_class = $self->get_content_body_parser_class($self->get_content_type($c));    | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $parser = exists($args{current_parser}) ?   | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $args{current_parser} :  | 
| 
113
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
249
 | 
       $parser_class->new(ctx=>$c, request_model=>$self );  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
114
 | 
   $parser->{context} = $args{context} if exists $args{context}; ## TODO ulgy  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
195
 | 
   return my %request_args = $parser->parse(\@ns, \@rules);  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_content_type {  | 
| 
121
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
0
  
 | 
99
 | 
   my ($self, $c) = @_;  | 
| 
122
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
   my $ct = $c->req->content_type;  | 
| 
123
 | 
33
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
3362
 | 
   return 'application/x-www-form-urlencoded' if !$ct && $c->req->method eq 'GET';  | 
| 
124
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
135
 | 
   return 'application/x-www-form-urlencoded' if $self->get_content_in eq 'query';  | 
| 
125
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
   return $ct;  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_namespace {  | 
| 
129
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
0
  
 | 
96
 | 
   my ($self, %args) = @_;  | 
| 
130
 | 
33
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
99
 | 
   return @{$args{current_namespace}} if exists($args{current_namespace});  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
131
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
   return grep { defined $_ } $self->namespace;  | 
| 
 
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
    | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_content_body_parser_class {  | 
| 
135
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
0
  
 | 
146
 | 
   my ($self, $content_type) = @_;  | 
| 
136
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
   return my $parser_class = CatalystX::RequestModel::content_body_parser_for($content_type);  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_attribute_value_for {  | 
| 
140
 | 
96
 | 
 
 | 
 
 | 
  
96
  
 | 
  
0
  
 | 
220
 | 
   my ($self, $attr) = @_;  | 
| 
141
 | 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3217
 | 
   return $self->$attr;  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub nested_params {  | 
| 
145
 | 
30
 | 
 
 | 
 
 | 
  
30
  
 | 
  
1
  
 | 
890
 | 
   my $self = shift;  | 
| 
146
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
   my %return;  | 
| 
147
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
   foreach my $p ($self->properties) {  | 
| 
148
 | 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
286
 | 
     my ($attr, $meta) = %$p;  | 
| 
149
 | 
105
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
265
 | 
     if(my $predicate = $meta->{attr_predicate}) {  | 
| 
150
 | 
92
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
198
 | 
       if($meta->{omit_empty}) {  | 
| 
151
 | 
88
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3643
 | 
         next unless $self->$predicate;  # skip empties when omit_empty=>1  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
257
 | 
     my $value = $self->get_attribute_value_for($attr);  | 
| 
156
 | 
96
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
526
 | 
     if( (ref($value)||'') eq 'ARRAY') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
       my @gathered = ();  | 
| 
158
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
       foreach my $v (@$value) {  | 
| 
159
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
         if(Scalar::Util::blessed($v)) {  | 
| 
160
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
           my $params = $v->nested_params;  | 
| 
161
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
           push @gathered, $params if keys(%$params);  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
163
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
           push @gathered, $v;  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
167
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
       $return{$attr} = \@gathered;  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif(Scalar::Util::blessed($value) && $value->can('nested_params')) {   | 
| 
169
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
       my $params = $value->nested_params;  | 
| 
170
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
       next unless keys(%$params);  | 
| 
171
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       $return{$attr} = $params;  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
173
 | 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
245
 | 
       $return{$attr} = $value;  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
176
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
158
 | 
   return \%return;  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }   | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get {  | 
| 
180
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
 
 | 
   my ($self, @fields) = @_;  | 
| 
181
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $p = $self->nested_params;  | 
| 
182
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my @got = @$p{@fields};  | 
| 
183
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return @got;  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 CatalystX::RequestModel::DoesRequestModel - Role to provide request model API  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Generally you will apply this role via L<CatalystX::RequestModel>  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package Example::Model::AccountRequest;  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Moose;  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use CatalystX::RequestModel;  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     extends 'Catalyst::Model';  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     namespace 'person';  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     content_type 'application/x-www-form-urlencoded';  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     has username => (is=>'ro', property=>{always_array=>1});    | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     has first_name => (is=>'ro', property=>1);  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     has last_name => (is=>'ro', property=>1);  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     has notes => (is=>'ro', property=>+{ expand=>'JSON' });  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See L<CatalystX::RequestModel> for a more general overview.  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A role that gives a L<Catalyst::Model> the ability to indicate which of its attributes should be  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 consider request model data, as well as additional need meta data so that we can process it  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 properly.  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Since we need to wrap C<has> you should never apply this role manually but rather instead use  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L<CatalystX::RequestModel> to apply it for you.   If you need to customize this role you will  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 also need to subclass L<CatalystX::RequestModel> and have that new subclass apply you custom  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 role.   Please ping me if you really need this since I guess we could change L<CatalystX::RequestModel>  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to make it easier to supply a custom role, just let me know your use case.  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This class defines the following public API  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 nested_params  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns all the attributes marked as request properties in the form of a hashref.  If any of the  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 properties refer to an array or indexed value, or an object, we automatically follow that to   | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 return all the property data below.  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Attributes that are empty will be left out of the return data structure.  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Easiest way to get all your data but then again you get a structure that is very tightly tied to  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 your request model.    | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 get  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Accepts a list of attributes that refer to request properties and returns their values.  In the case  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 when the attribute listed has no value, you will instead get an C<undef>.  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 EXCEPTIONS  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This class can throw the following exceptions:  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Invalid Request Content Body  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If we can't create an instance of the request model we throw a L<CatalystX::RequestModel::Utils::BadRequest>.  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This will get interpretated as an HTTP 400 status client error if you are using L<CatalystX::Errors>.  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See L<CatalystX::RequestModel>.  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See L<CatalystX::RequestModel>.  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See L<CatalystX::RequestModel>.  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    |