File Coverage

blib/lib/RapidApp/View/JSON.pm
Criterion Covered Total %
statement 33 57 57.8
branch 4 18 22.2
condition 2 21 9.5
subroutine 10 12 83.3
pod 1 4 25.0
total 50 112 44.6


line stmt bran cond sub pod time code
1             package RapidApp::View::JSON;
2              
3 4     4   2030 use Moose;
  4         9  
  4         31  
4 4     4   23229 use namespace::autoclean;
  4         8  
  4         38  
5 4     4   316 BEGIN { extends 'Catalyst::View'; }
6              
7 4     4   4347 use RapidApp::JSON::MixedEncoder;
  4         9  
  4         358  
8 4     4   25 use Scalar::Util 'blessed', 'reftype';
  4         9  
  4         175  
9 4     4   25 use HTML::Entities;
  4         9  
  4         257  
10 4     4   27 use RapidApp::Util qw(:all);
  4         6  
  4         4047  
11              
12             =head1 NAME
13              
14             RapidApp::View::JSON
15              
16             =head1 DESCRIPTION
17              
18             This view displays content as a JSON packet that will be used by RapidApp's
19             client-side javascript.
20              
21             It also handles the awkwardness of passing data back through ExtJS's form
22             submissions. Form submissions require the data to be returned as *html*
23             so that the browser doesn't screw it up, and then the rendered text of the
24             HTML should be valid JSON that the Javascript uses.
25              
26             This is also where error/exceptions are processed. This view used to have complex
27             code for error reporting but this was removed a long time ago. This view is still in
28             need of general cleanup
29              
30             =cut
31              
32             has 'encoding' => ( is => 'rw', isa => 'Str', default => 'utf-8' );
33              
34             has 'encoder' => ( is => 'rw', isa => 'RapidApp::JSON::MixedEncoder', lazy_build => 1 );
35             sub _build_encoder {
36 2     2   21 return RapidApp::JSON::MixedEncoder->new
37             }
38              
39             sub process {
40 11     11 1 19454 my ($self, $c)= @_;
41            
42 11         37 my $json;
43            
44 11 50       33 if (my $err = $c->stash->{exception}) {
45 0 0       0 $c->log->debug("RapidApp::View::JSON exception: $err") if ($c->debug);
46            
47 0         0 $c->res->header('X-RapidApp-Exception' => 1);
48 0         0 $c->res->status(500);
49            
50 0   0     0 my $msg= $self->getUserMessage($err) || "An internal error occured: \n\n" . $err;
51 0   0     0 my $title= $self->getUserMessageTitle($err) || 'Error';
52            
53 0         0 $json= {
54             exception => \1,
55             success => \0,
56             rows => [],
57             results => 0,
58             msg => $msg,
59             title => $title,
60             };
61             }
62             else {
63             $json= $c->stash->{json} || $c->stash->{jsonData} || $c->stash->{controllerResult}
64 11 50 33     647 or die "None of exception, json, jsonData, controllerResult were specified. Cannot render.";
65             }
66            
67 11         1782 $self->setJsonBody($c, $json);
68             }
69              
70             # Either set the body to a json packet (for normal ajax requests) or html-encoded json
71             # for file-upload forms.
72             sub setJsonBody {
73 11     11 0 33 my ($self, $c, $json)= @_;
74            
75 11   33     47 my $encoding= $c->stash->{encoding} || $self->encoding;
76 11         40 my $rct= $c->stash->{requestContentType};
77            
78 11 50       831 (!ref $json) or $json= $self->encoder->encode($json);
79            
80 11         768 $c->res->header('Cache-Control' => 'no-cache');
81            
82 11 50       2889 if ($rct eq 'text/x-rapidapp-form-response') {
83 0         0 my $hdr= $c->res->headers;
84 0         0 my %headers= map { $_ => $hdr->header($_) } $hdr->header_field_names;
  0         0  
85 0         0 my $headerJson= $self->encoder->encode(\%headers);
86            
87 0         0 $c->res->content_type("text/html; charset=$encoding");
88 0         0 $c->res->body(
89             '<html><body>'.
90             '<textarea id="json">'.encode_entities($json).'</textarea>'.
91             '<textarea id="header_json">'.encode_entities($headerJson).'</textarea>'.
92             '</body></html>'
93             );
94             }
95             else {
96 11         53 $c->res->content_type("text/javascript; charset=$encoding");
97 11         2320 $c->res->body($json);
98             }
99             }
100              
101             sub getUserMessage {
102 0     0 0   my ($self, $err)= @_;
103 0 0         blessed($err) or return undef;
104 0   0       my $method= $err->can('userMessage') || return undef;
105 0           my $str= ashtml $err->$method();
106 0 0 0       defined $str && length($str) or return undef;
107 0           return $str;
108             }
109              
110             sub getUserMessageTitle {
111 0     0 0   my ($self, $err)= @_;
112 0 0         blessed($err) or return undef;
113 0   0       my $method= $err->can('userMessageTitle') || return undef;
114 0           my $str= ashtml $err->$method();
115 0 0 0       defined $str && length $str or return undef;
116 0           return $str;
117             }
118              
119             1;